如何防止 CodeFirst 尝试在我的数据库上运行迁移?
我收到 SqlException
并抛出以下错误消息:
Invalid object name 'dbo.__MigrationHistory'.
我的日志框架正在捕获并记录这些异常。我需要防止异常发生,以便我的应用程序不会生成大量虚假日志消息。
我了解 __MigrationHistory
表是代码优先迁移的一部分。我确实使用代码优先,但我不使用它的迁移。 (该项目使用 FluentMigrator 代替。)根据 this blog post和 this answer , 要禁用错误,我需要执行以下操作:
static InstitutionContext()
{
System.Data.Entity.Database.SetInitializer<InstitutionContext>(null);
}
(当然,这是针对名为 InstitutionContext
的 DbContext
对象。)
我已经这样做了,并验证了代码行是否被命中。但是,我仍然在日志中收到错误。
This answer解释了正在发生的事情,我认为这基本上是正确的。简而言之,EF 正在探测 __MigrationsHistory
表,在找不到它时引发异常,然后继续而不对迁移执行任何操作。但是答案并没有解释如何抑制异常的发生。
如何防止 EF Code First 迁移尝试运行并抛出其 SqlException
?
更新 1
我尝试通过 App.config/Web.config 文件配置设置,但也没有用。我还尝试将它从我的 DbContext
上的静态方法移动到它自己的配置类,如下所示:
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration()
{
SetDatabaseInitializer<InstitutionContext>(null);
}
}
该类与 DbContext
应在同一个程序集中。这也不起作用。
更新 2
问题原来与 Unity 容器有关,以及 EF 和 Unity 是如何交互的(鉴于我的配置方式)。参见 my answer下面。
最佳答案
作为对我的问题注释的评论,我所做的应该有效。问题出在我的项目如何使用 Unity 依赖项注入(inject)容器。
对于正在注册的所有类型,我还配置了一个虚拟方法拦截器。我正在像这样注册和配置我的 DbContext
:
Container.RegisterType<IInstitutionContext, InstitutionContext>();
Container.Configure<Interception>()
.SetInterceptorFor(typeof(InstitutionContext),
new VirtualMethodInterceptor());
问题是 VirtualMethodInterceptor
。拦截器导致 InstitutionContext
类被包装。
Entity Framework 6 维护一个注册表,将 DbContext
类型与其配置的 DbInitializer
相关联。当它第一次看到新类型的 DbContext
时,它会在其内部注册表中查找应该调用哪个 DbInitializer
。它尝试根据 DbContext
的类型找到 DbInitializer
。如果它没有找到已注册的 DbInitializer
,它会使用默认的初始化程序,即 CreateDatabaseIfNotExists
。
但是当 VirtualMethodInterceptor
被配置为给定的 DbContext
类型(在我的例子中,InstitutionContext
),Unity 容器将不会实例化InstitutionContext
直接。相反,它包装 InstitutionContext
以便能够拦截虚拟方法。当 EF6 尝试定位类型以查找其 DbInitializer
时,它会检查 DbContext 的类型,这是一个包装类型,不是 InstitutionContext
键入。因此它永远找不到匹配的类型,并回退到使用默认的数据库初始化器。
删除 DbContext
类型的拦截器解决了这个问题。
tl;dr: 确保您的 DbContext
未被其他类型包装。要使 EF6 的 DbInitializer
配置正常工作,它必须检查正确的 DbContext
类型。如果 DbContext
是从具有已注册的 DbInitializer
的类型继承的,它将不起作用,如果 DbContext
是包装器类型。
关于c# - 在使用 Unity 配置依赖注入(inject)时,如何防止 EF Code First 尝试在我的数据库上运行迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39400102/