4

抽象ベースから継承するコンテキスト クラスがありますAuditableDbContext : DbContext。はAuditableDbContext2 つのパラメーターを使用します。1 つは監査者用で、もう 1 つは監査対象のコンテキスト用です。

継承されたクラスには、null パラメーターを使用して他のコンストラクターを呼び出す既定のパラメーターなしのコンストラクターがあり、最終コンストラクターではDatabase.SetInitializer<MyDbContext>(null)、基本コンストラクターを呼び出した後に呼び出します。

問題は、これを行っても、アプリケーションの起動時にデータベース サーバーで db migration 呼び出しが引き続き発生することです。

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);
  }
}

データベースで見られるクエリは、2 つの一般的な移行クエリです...

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

Entity Framework がこれらのクエリを作成するのを止める方法についてのアイデアはありますか?

4

2 に答える 2

12

これは、静的コンストラクターで行うか、コンテキストをインスタンス化する前に行う必要があります。

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

このような古い質問、特に回答済みとしてマークされている質問に返信して申し訳ありませんが、それは私を悩ませており、とにかく解決策を提供したかった.

問題は、LINQPad が DbContext クラスのサブクラスを作成することです。を呼び出しDatabase.SetInitializer<MyDbContext>(null)た場合、MyDbContext のインスタンスを作成している限り機能します。ただし、設計上、LINQPad はコードを MyDbContext から派生したクラスにコンパイルします。MyDbContext を封印すると、LINQPad はそれを使用できなくなります。

回避策は、リフレクションを使用してDatabase.SetInitializerMyDbContext のインスタンス コンストラクターを呼び出すことです。これは、コンテキストのすべてのインスタンスに対して不必要に呼び出していることを意味しますが、何も害はありません。しかし、これにより、 this.GetType() を使用して LINQPad が作成するサブクラスにアクセスできるようになり、リフレクションを使用して を呼び出すことができますSetInitializer

ただし、メソッドの非汎用バージョンが追加された場合はいいでしょう。

この Gist には、リフレクションを使用して を呼び出す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 に答える