仅将 IDbInterceptor 挂钩到 EntityFramework DbContext 一次

问题描述 投票:0回答:2

IDbCommandInterceptor
界面没有很好的文档记录。我只找到了一些稀缺的教程:

还有一些问题:


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

1 - 静态

DbInterception
类:

DbInterception.Add(new MyCommandInterceptor());

2 - 在

DbConfiguration
课堂上执行上述建议

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

3 - 使用配置文件:

<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
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() { }
    }
}

但是正确/预期的方法是什么?

c# entity-framework logging entity-framework-6 interceptor
2个回答
11
投票

我发现我的

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

6
投票

docs建议您可以将其放入

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

重要的是它只会被调用一次。

© www.soinside.com 2019 - 2024. All rights reserved.