显式调用DatabaseInitializer

时间:2012-11-01 17:44:36

标签: entity-framework ef-code-first entity-framework-5 dbcontext

我在两个服务项目之间共享的程序集中有一个DbContext。我有两个项目设置为在Visual Studio中启动调试。这会创建一个竞争条件,其中每个服务中的DatabaseInitializer尝试在启动时更新数据库。

为防止出现这种情况,我修改了DbContext,如下所示,以防止DatabaseIntializer自动注册。

public EntityContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<EntityContext>(null);
    }
}

我想禁用DatabaseInitializer内部的DbContext,这样我就不必在每个碰巧引用我SetInitializer()的项目中复制DbContext次调用,根据我所读到的内容,覆盖OnModelCreating()似乎就是这样做的。

这会阻止DatabaseInitializer自动运行,但我想创建一个单独的项目,我可以手动运行以更新数据库。所以我做了类似以下的事情:

static void Main(string[] args)
{
    Database.SetInitializer(new CreateDatabaseIfNotExists<EntityContext>());
    new EntityContext().Database.Initialize(true);
}

问题是这似乎不起作用 - OnModelCreating()方法中设置的空初始值设定项显然会覆盖我在SetInitializer()的任何其他调用中指定的任何内容。即使我将SetIntializer(null)调用移动到EntityContext类的静态构造函数以保证它首先被调用它仍然不起作用。它的唯一工作方式是我手动调用初始化程序如下:

static void Main(string[] args)
{
    new CreateDatabaseIfNotExists<EntityContext>()
        .InitializeDatabase(new EntityContext());
}

但直接调用DatabaseInitializer.InitializeDatabase()似乎不对,因为实体框架基础结构应该调用它。

这是EF Code First中的错误吗?什么是“正确”的方法?

更新:我决定使用Update-Database程序包管理器控制台命令手动创建数据库脚本比尝试以编程方式更新数据库的这个kludgey项目更好的解决方案。

1 个答案:

答案 0 :(得分:1)

只要在调用禁用初始化程序之后进行设置初始化程序的调用,这就应该可以工作。在您的情况下,OnModelCreating或静态EntityContext初始化程序都不会这样做。只有在第一次使用EntityContext时才会调用静态初始化程序,在您的示例中,直到调用SetInitializer之后才会调用静态初始化程序。

在进行SetInitializer调用之前,您可以考虑强制调用静态初始值设定项。例如,这应该有效:

using (var context = new EntityContext())
{
    Database.SetInitializer(new CreateDatabaseIfNotExists<EntityContext>());
    context.Database.Initialize(true);
}