仅将IDbInterceptor挂钩到EntityFramework DbContext一次

IDbCommandInterceptor接口没有很好的文档记录。 我只发现了一些稀缺的教程:

  • 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
  • https://msdn.microsoft.com/en-us/data/dn469464%28v=vs.113%29.aspx

还有一些问题:

  • entity framework6 – 定时查询
  • 从IDbCommandInterceptor的实现中获取DbContext

这些是我发现的挂钩建议:

1 – 静态DbInterception类:

 DbInterception.Add(new MyCommandInterceptor()); 

2 – 在DbConfiguration类中执行上述建议

 public class MyDBConfiguration : DbConfiguration { public MyDBConfiguration() { DbInterception.Add(new MyCommandInterceptor()); } } 

3 – 使用配置文件:

      

虽然我无法弄清楚如何将DbConfiguration类挂钩到DbContext,也不知道如何将配置方法的type部分放入。 我发现的另一个例子似乎建议您编写记录器的命名空间:

 type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework" 

我注意到DataBaseLogger实现了IDisposableIDbConfigurationInterceptor
IDbInterceptorIDbCommandInterceptor也实现了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() { } } } 

但是,正确/有意的方法是什么?

我发现我的DbContext类只需要具有DbConfigurationType属性,以便在运行时附加配置:

 [DbConfigurationType(typeof(MyDBConfiguration))] public partial class MyDbContext // : DbContext { public MyDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { } } public class MyDBConfiguration : DbConfiguration { public MyDBConfiguration() { this.AddInterceptor(new MyCommandInterceptor()); } } 

文档建议你可以把它放在Application_Start

 protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); DbInterception.Add(new SchoolInterceptorTransientErrors()); DbInterception.Add(new SchoolInterceptorLogging()); } 

重要的是它只被召唤一次。