将EntityFramework与Code First方法一起使用时,通常从DbContext派生并为您拥有的所有实体类型创建DbSet属性 .
我不能这样做,因为我的软件可以用于提供在编译时未知的新实体类型的模块 .
所以我想在运行时确定可用的实体类型列表 .
我得到了部分使用此代码:
public class MyDbContext: DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
// Register all types that derive from ModelBase as entity types
var entityTypes = assembly
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(ModelBase)));
foreach (var type in entityTypes)
{
entityMethod.MakeGenericMethod(type)
.Invoke(modelBuilder, new object[] { });
}
}
}
}
但是,当我这样做时, OnModelCreating
永远不会被调用 . 我必须在我的 class 添加一个DbSet . 我甚至不能将DbSet设为私有或内部,它必须是公共的,这使得它成为一个丑陋的解决方法:
public DbSet<DummyType> DummyTypes { get; set; }
public MyDbContext(string connectionName):
base(connectionName)
{
// Force initialization to make sure OnModelCreating
// has been called after leaving the constructor
DummyTypes.Count();
}
添加此变通方法时,我可以通过调用 DbContext.Set<EntityType>()
方法访问DbSets,因此一切都按预期工作 .
Question: 有没有办法在不向我的类添加公共DbSet属性的情况下实现相同的功能?
1 回答
你能不能以更加静态的方式解决问题?例如,每个库也可以提供自己的
DbContext
实现 . 如果库静态地不知道彼此,那么它们就没有静态的方法来为其他库中的类提供导航属性 . 然后你可以拥有独立的DbContexts
,每个库一个 . 如何在主代码中使用它们?这取决于你的实现,但我想你可以搞清楚 .当库互相引用时,可能没有循环,因此,它们形成逻辑拓扑排序 . 例如,如果库A和B引用C,则可以在A和B中使用
DbContexts
而不在C中,如果它不使用它自己的实体 .传统上,除非您需要迁移,否则没有任何东西可以阻止您在EF中执行此操作 . 现在,对于同一数据库中的不同
DbContexts
,EF supports迁移 .