我们说我有一个基础datacontext:
public class BaseContext : DbContext {
public DbSet<User> Users { get; set; }
public BaseContext(): base("default")
{
Database.SetInitializer(new BaseContextInitializer());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new UserConfiguration());
}
}
public class BaseContextInitializer : IDatabaseInitializer<BaseContext>
{
private static readonly Lazy<bool> ShouldInitializeDatabase = new Lazy<bool>(() =>
string.IsNullOrWhiteSpace(
ConfigurationManager.AppSettings[
"InitializeDatabase"]));
public void InitializeDatabase(BaseContext context)
{
if (!ShouldInitializeDatabase.Value) return;
bool dataBaseExists;
using (new TransactionScope(TransactionScopeOption.Suppress))
dataBaseExists = context.Database.Exists();
if (dataBaseExists)
{
try
{
if (context.Database.CompatibleWithModel(true))
return;
context.Database.Delete();
}
catch (NotSupportedException)
{
context.Database.Delete();
}
}
context.Database.Create();
context.Database.ExecuteSqlCommand("alter table Users add constraint UniqueUserEmail unique (Email)");
Seed(context);
}
protected virtual void Seed(BaseContext context)
{
// seeding code
}
}
我尝试创建一个派生的datacontext,只需要几个附加集:
public class DerivedContext : BaseContext {
public DbSet<Admin> Admins { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new AdminConfiguration());
}
}
我使用SimpleInjector并注册上下文(在服务中使用),如下所示:
container.RegisterPerWebRequest<DerivedContext, DerivedContext>();
这样,只创建BaseContext
个表。
如果我加上这个:
container.RegisterPerWebRequest<BaseContext, DerivedContext>();
container.RegisterPerWebRequest<DerivedContext, DerivedContext>();
然后创建派生集,但初始化程序不会运行。
我错过了什么?做这样的事情的正确模式是什么?
答案 0 :(得分:0)
所以这似乎有效,并且不涉及复制派生类中的所有内容:
// make it generic
public class BaseContextInitializer<T> : IDatabaseInitializer<T>
{
// ...
public void InitializeDatabase(T context)
{
// ...
}
}
// now pass the derivedcontext in the derived initializer
public class DerivedContextInitializer : BaseContextInitializer<DerivedContext>
{
// overrides etc. etc.
}
// set the initializer to be the derived one
public class DerivedContext : BaseContext {
public DbSet<Admin> Admins { get; set; }
public DerivedContext(): base("default")
{
Database.SetInitializer(new DerivedContextInitializer());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new AdminConfiguration());
}
}
所以这样可以保持干燥和清洁。由于某种原因,我仍然无法摆脱肮脏的感觉。
坐了一段时间后,我可以验证这种方法是否有效。但是,EF确实不是为了考虑继承模型,而是人们所期望的(可能是有充分理由的)。从长远来看,它可能更好,没有继承并且只有一个上下文,即使它意味着一些代码重复开始。