仅将 IDbInterceptor 挂钩到 EntityFramework DbContext 一次 [英] Hooking IDbInterceptor to EntityFramework DbContext only once

查看:23
本文介绍了仅将 IDbInterceptor 挂钩到 EntityFramework DbContext 一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

IDbCommandInterceptor 接口没有很好的文档记录.而且我只找到了一些稀缺的教程:

The IDbCommandInterceptor interface is not very well documented. And I've only found a few scarce tutorials on it:

还有几个 SO 问题:

And a few SO questions:

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

These are the suggestions on hooking I've found:

1 - 静态 DbInterception 类:

DbInterception.Add(new MyCommandInterceptor());

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

2 - Doing the above suggestion in a DbConfiguration class

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

3 - 使用配置文件:

<entityFramework>
  <interceptors>
    <interceptor type="EFInterceptDemo.MyCommandInterceptor, EFInterceptDemo"/>
  </interceptors>
</entityFramework>

<小时>

虽然我不知道如何将 DbConfiguration 类与 DbContext 挂钩,也不知道在 config 方法的 type 部分中放入什么.我发现的另一个例子似乎暗示了你写一个记录器的命名空间:


Although I couldn't figure out how to hook the DbConfiguration class to the DbContext, and neither what to put in the type part of the config method. Another example I found seemed to suggest that you write the namespace of a logger:

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

我注意到 DataBaseLogger 实现 IDisposableIDbConfigurationInterceptor
IDbInterceptor.IDbCommandInterceptor 也实现了 IDbInterceptor,所以我尝试(没有成功)将其格式化为:

I noted that DataBaseLogger implements IDisposable, IDbConfigurationInterceptor and
IDbInterceptor. IDbCommandInterceptor also implements IDbInterceptor, so I tried (without success) to format it like this:

type="DataLayer.Logging.MyCommandInterceptor, DataLayer"

当我直接调用静态 DbInterception 类时,它每次调用都会添加另一个拦截器.所以我快速而肮脏的解决方案是使用静态构造函数:

And when I called the static DbInterception class directly, it added another interceptor every call. So my quick and dirty solution was to utilize static constructors:

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

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

But what are the proper/intended ways to do it?

推荐答案

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

I figured out that my DbContext class just needed to have the DbConfigurationType attribute, to attach a configuration at runtime:

[DbConfigurationType(typeof(MyDBConfiguration))]
public partial class MyDbContext // : DbContext
{
    public MyDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
    { }
}

public class MyDBConfiguration : DbConfiguration {
    public MyDBConfiguration() {
        this.AddInterceptor(new MyCommandInterceptor());
    }
}

这篇关于仅将 IDbInterceptor 挂钩到 EntityFramework DbContext 一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆