4

我有一个从抽象基类继承的上下文类AuditableDbContext : DbContext。它AuditableDbContext有两个参数,一个用于审计员,一个用于审计的上下文。

在继承的类中,我有一个默认的无参数构造函数,它使用空参数调用其他构造函数,然后在Database.SetInitializer<MyDbContext>(null)调用基本构造函数后调用的最终构造函数中。

问题是即使我这样做了,当应用程序启动时,我仍然会在数据库服务器上获得 db 迁移调用。

public abstract class AuditableContext : DbContext
{
  public AuditableContext(IAuditor auditor, DbContext auditContext)
  {
    // params can be null resulting in no auditing
    // initialization stuff here...
  }
}

public class MyDbContext : AuditableContext
{
  // DbSets here...

  public MyDbContext() : this(null, null) {}

  public MyDbContext(IAuditor auditor) : this(auditor, null) {}

  public MyDbContext(IAuditor auditor, DbContext auditContext) 
  : base(auditor, auditContext)
  {
    Database.SetInitializer<MyDbContext>(null);
  }
}

我在数据库上看到的查询是两个常见的迁移查询...

SELECT [GroupBy1].[A1] AS [C1]
FROM ( SELECT COUNT(1) AS [A1]
FROM [dbo].[__MigrationHistory] AS [Extent1]
)  AS [GroupBy1]

SELECT TOP (1) 
[Extent1].[Id] AS [Id], 
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC

关于如何阻止实体框架进行这些查询的任何想法?

4

2 回答 2

12

您将需要在静态构造函数中执行此操作,或者在实例化 Context 之前更好。

static MyDbContext() {
    Database.SetInitializer<MyDbContext>(null);
}
于 2013-05-24T04:25:34.773 回答
9

很抱歉回答这么老的问题,尤其是标记为已回答的问题,但它一直困扰着我,无论如何我都想提供一个解决方案。

问题是 LINQPad 创建了 DbContext 类的子类。因此,当您调用时Database.SetInitializer<MyDbContext>(null),只要您正在创建 MyDbContext 的实例,它就会起作用。但是按照设计,LINQPad 将您的代码编译成一个派生自 MyDbContext 的类。如果您将 MyDbContext 密封,LINQPad 将无法使用它。

解决方法是在 MyDbContext 的实例构造函数中使用反射调用Database.SetInitializer。这意味着您不必要地为上下文的每个实例调用它,但它不会伤害任何东西。但这允许您使用 this.GetType() 来访问 LINQPad 创建的子类,然后您可以使用反射来调用SetInitializer.

如果添加了该方法的非通用版本会很好。

这个要点有一个使用反射调用的例子Database.SetInitializer

var databaseType = typeof( Database );
var setInitializer = databaseType.GetMethod( "SetInitializer", BindingFlags.Static | BindingFlags.Public );

var thisType = GetType( );
var setInitializerT = setInitializer.MakeGenericMethod( thisType );

setInitializerT.Invoke( null, new object[] { null } );
于 2014-04-16T20:15:10.623 回答