IDbCommandInterceptor
インターフェイスの説明はあまりよくありません。そして、私はそれにいくつかの希少なチュートリアルを見つけた:EntityFrameworkへのIDbInterceptorを1回だけDbContextにフックする
- http://www.entityframeworktutorial.net/entityframework6/database-command-interception.aspx
- https://msdn.microsoft.com/en-us/data/jj556606%28v=vs.113%29.aspx
- https://entityframework.codeplex.com/wikipage?title=Interception
- https://www.tutorialspoint.com/entity_framework/entity_framework_command_interception.htm
-
とSOいくつかの質問を:
これらは私が見つけたフックの提案です:
を - 静的DbInterception
クラス:
DbInterception.Add(new MyCommandInterceptor());
- configファイルの使用 - DbConfiguration
クラス
public class MyDBConfiguration : DbConfiguration {
public MyDBConfiguration() {
DbInterception.Add(new MyCommandInterceptor());
}
}
に上記の提案をしている:私はフックする方法を見つけ出すことができませんでしたが、
<entityFramework>
<interceptors>
<interceptor type="EFInterceptDemo.MyCommandInterceptor, EFInterceptDemo"/>
</interceptors>
</entityFramework>
をDbConfiguration
クラスをDbContextに割り当て、configメソッドのtype
部分には何も入れません。
type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework"
私はDataBaseLogger
がIDisposable
、IDbConfigurationInterceptor
と IDbInterceptor
を実装して次のように述べている。Another example I foundあなたはロガーの名前空間を作成することを示唆しているように見えました。 IDbCommandInterceptor
もIDbInterceptor
を実装していたので、私はこのようにそれをフォーマットする(成功せず)みました:
type="DataLayer.Logging.MyCommandInterceptor, DataLayer"
そして、私が直接静的DbInterception
クラスを呼び出したときに、それは別の迎撃にすべての呼び出しを追加しました。だから私のすばやく解決策は、静的なコンストラクタを利用することでした:
//This partial class is a seperate file from the Entity Framework auto-generated class,
//to allow dynamic connection strings
public partial class MyDbContext // : DbContext
{
public Guid RequestGUID { get; private set; }
public MyDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
DbContextListeningInitializer.EnsureListenersAdded();
RequestGUID = Guid.NewGuid();
//Database.Log = m => System.Diagnostics.Debug.Write(m);
}
private static class DbContextListeningInitializer
{
static DbContextListeningInitializer() //Threadsafe
{
DbInterception.Add(new MyCommandInterceptor());
}
//When this method is called, the static ctor is called the first time only
internal static void EnsureListenersAdded() { }
}
}
しかし、それを行うにはどうすればよいですか?
[DbConfigurationType(typeof(MyDBConfiguration))]
public partial class MyDbContext // : DbContext
{
public MyDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{ }
}
public class MyDBConfiguration : DbConfiguration {
public MyDBConfiguration() {
this.AddInterceptor(new MyCommandInterceptor());
}
}
これはスレッドセーフではないと思います。別のスレッドにMyDBConfiguration2と同様のコンストラクタ本体があるとどうなりますか?次に、両方のDbContextのMyCommandInterceptorが2回登録されます。 –
あなたの 'MyDBConfiguration'コンストラクタで、あなたは' this.AddInterceptor() 'メソッドを持っている静的クラスを使う必要はありません。 –
@JohnZabroski DbInterception.Add()がスレッドセーフではないことを意味しますか? [ドキュメント](https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.interception.dbinterception.add(v = 1173).aspx)ではそうは言いませんが、私はあなたが正しいと思います。 Jan'splite'K。の提案は論理的な答えのように見えます。そして、それが動作することを確認するためにテストしました。それに応じて答えを更新。 –