IDbCommandInterceptor
接口没有很好的记录。而我只发现了一些稀缺的教程就可以了:连接IDbInterceptor到EntityFramework 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
-
等几个问题:
这些都是挂钩我已经找到了建议:
- 静态DbInterception
类:
DbInterception.Add(new MyCommandInterceptor());
- 做上述建议在DbConfiguration
类
public class MyDBConfiguration : DbConfiguration {
public MyDBConfiguration() {
DbInterception.Add(new MyCommandInterceptor());
}
}
- 使用配置文件:
<entityFramework>
<interceptors>
<interceptor type="EFInterceptDemo.MyCommandInterceptor, EFInterceptDemo"/>
</interceptors>
</entityFramework>
虽然我无法弄清楚如何挂钩DbConfiguration
类转换为DbContext,并且既不要在配置方法的type
部分放置什么。 Another example I found似乎表明,你写一个记录器的命名空间:
type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework"
我注意到,DataBaseLogger
实现IDisposable
,IDbConfigurationInterceptor
和
IDbInterceptor
。 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() { }
}
}
但什么是正确的/打算如何做到这一点?
我不认为这是线程安全的。如果另一个线程有MyDBConfiguration2和一个类似的构造函数体,会发生什么?那么这两个DbContext的都会有MyCommandInterceptor注册两次,对吧? –
在你的'MyDBConfiguration'构造函数中,你不必使用那个静态类,你有'this.AddInterceptor()'方法。 –
@JohnZabroski你的意思是说DbInterception.Add()不是线程安全的? [文档](https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.interception.dbinterception.add(v = vs.113).aspx)并不这么说,所以我会认为你是对的。 Jan'splite'K的建议看起来像是合乎逻辑的答案 - 我对它进行了测试以确认它是否有效。相应地更新答案。 –