如何在Entity Framework 6.0中禁用迁移

74

我正在尝试使用Entity Framework 6.0 rc1忽略“自动”迁移。我的问题是我现在不需要这个功能,每次我的应用程序运行时,我都可以看到所有实体日志尝试创建所有表。

提前感谢。


11
你尝试过使用Database.SetInitializer<TContext>(null)禁用数据库初始化器吗? - Pawel
3
晚了一点,但标题如果说“禁用自动迁移”会更准确,而不是基于代码的迁移。 - Savage
7个回答

51

您可以将此代码放入您的 app.config 文件的 entityFramework 部分中:

<contexts>
  <context type="YourNamespace.YourDbContext, YourAssemblyName" disableDatabaseInitialization="true"/>
</contexts>

这个 MSDN 页面详细介绍了Entity Framework Configuration Section


1
这是一种更好的永久禁用数据库初始化的方法。 - Tom Halladay
5
这个页面介绍了Entity Framework配置部分的所有内容:https://msdn.microsoft.com/zh-cn/data/jj556606 - KevinVictor
1
app.config是什么?你是不是指的是web.config - Muflix
1
我如何确定什么是YourAssemblyName - Muflix
1
要禁用初始化,您必须将disableDatabaseInitialization设置为true,而不是false。 - Carlos Teixeira
显示剩余3条评论

50

试一试:

internal sealed class Configuration : DbMigrationsConfiguration<YourContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }
}

更新:

您也可以尝试这个方法:

Database.SetInitializer<YourContextType>(new CreateDatabaseIfNotExists());

2
是的,现在它可以工作了。我猜我之前做错了什么。问题是我删除了我的 __migratioHistory 表和所有迁移文件。我执行了 Database.SetInitializer(new NullDatabaseInitializer<EfContext>()),与 Database.SetInitializer<TContext>(null) 相同,谢谢大家。 - Michel Borges
2
大家好,我想我的问题没有表达清楚。我意识到我的问题是我有一个继承自DbContext的抽象基类,名为DefaultDbContext。问题在于我使用了Database.SetInitializer<DefaultDbContext>(null),但正确的方式应该是Database.SetInitializer<ConcretClassA>(null)。谢谢! - Michel Borges
第一个答案对我来说似乎有效。我正在使用一种情况,其中我使用Code First创建小型模型,用于现有的数据库,我永远不会更改它。谢谢。 - Wade Hatler
1
一旦启用了迁移(添加了配置类),这两个解决方案都不会阻止迁移的运行。AutomaticMigrationsEnabled = false - 禁用了自动迁移数据库,而代码中没有迁移。此外,我的期望是避免使用CreateDatabaseIfNotExists初始化程序运行迁移。我希望EF将基于模型创建一个没有迁移的数据库。但是,在存在迁移的情况下,CreateDatabaseIfNotExists和MigrateDatabaseToLatestVersion的行为是相同的。 - SerjG
请查看博客链接:https://msdn.microsoft.com/zh-cn/magazine/dn818489.aspx - SerjG
我将 Database.SetInitializer<YourContextType>(new CreateDatabaseIfNotExists()); 放在静态构造函数中,以确保只调用一次并且不会暴露在我的 DLL 外部。 - dariogriffo

30

通过 web.config 查看 - https://msdn.microsoft.com/zh-cn/data/jj556606.aspx#Initializers

通过代码(奇怪的是,非常简单的答案)

public class MyDB : DbContext
{
    public MyDB()
    {
        Database.SetInitializer<MyDB>(null);
    }
}

或者在 Global.asax.cs 中

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // ...

        Database.SetInitializer<MyDB>(null);

        /// ...

    }
}

2
对于 Code First EF,这是最干净的答案。 - Brain2000
2
不要将其放在 DbContext 的构造函数中。 - Issa Fram
4
你会把它放在哪里?为什么不放在构造函数里?(这是真正的问题,不是讽刺) - Aaron Sherman
1
将实体类构造函数中的数据库初始化器设置为空会使初始视图生成速度比在实例化db上下文后将初始化器设置为空要快得多。在我的应用程序中,第一次数据库查询有1-1/2分钟的延迟。发现/修复了一些独立的关联,并降至55秒。在实例化db上下文后设置迁移初始化器将第一次调用时间缩短到15秒。将初始化器的空值设置移动到实体类构造函数中,将第一个调用延迟减少到只有几秒钟......就这样! - IdahoB
5
就我个人而言,我认为将SetInitializer添加到我的DbContext类的静态构造函数中是最简洁的方法。 - Michal Ciechan
显示剩余4条评论

4

如果您在寻找一个简单的答案来禁用迁移,因为您键入了“Enable-Migrations”,现在事情并没有按照您预期的方式工作,比如没有运行您认为应该运行的种子方法,那么请查看解决方案资源管理器并删除迁移文件夹。这将阻止代码查找迁移配置以查找初始化代码。要重新获取迁移文件夹,只需再次运行“Enable-Migrations”。


你可以运行 "Enable-Migrations -Force" 命令。 - Fernando Torres

3
我犯的错误是在上下文被初始化后才调用Database.SetInitializer(null);。确保禁用迁移的最佳方法是在应用程序启动时为所有上下文进行上述调用。我更喜欢这种方法,而不是在app.config中设置它,因为我可以使用我的容器来定位我的上下文,然后构造一个调用。
var migrationsMethod = typeof(System.Data.Entity.Database).GetMethod("SetInitializer");
foreach (var contextType in allContextTypes)
{
    migrationsMethod.MakeGenericMethod(contextType).Invoke(null, new object[] { null });                            
}

好奇,你是如何获取allContextTypes的? - Issa Fram
还有一个问题,你好奇如何查询所有上下文。 - katit

1

禁用自动迁移也可以在调用enable-migrations命令(创建Configuration类)期间进行配置,使用EnableAutomaticMigration参数并将其值设置为false

enable-migrations -EnableAutomaticMigration:$false -ContextTypeName FullyQualifiedContextName

这将创建一个Configuration类,将AutomaticMigrationsEnabled属性设置为false,就像上面的答案中一样。


在Entity Framework教程页面中这篇文章中提到了enable-migrations命令的EnableAutomaticMigration参数(但是他们使用默认值true)。


EnableAutomaticMigration 今天默认始终为 false。 - Fernando Torres
自动迁移的目的是什么?似乎每个人都讨厌它们。 - Fernando Torres
这部分的示例为 - ContextTypeName FullyQualifiedContextName。 - Fernando Torres

1
尝试这个,在你的MyContext类中添加这行代码,在调用MyContext构造函数之前将调用它。这将停止创建数据库,同时也不会在连接的数据库中添加表。基本上,这行代码禁用了默认的Code-First数据库初始化策略,该策略通常具有默认策略CreateDatabaseIfNotExists。
static MyContext()
{
       System.Data.Entity.Database.SetInitializer<MyContext>(null);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接