gpt4 book ai didi

autofac - 使用 MiniProfiler 和 EF 5 和 Autofac 分析 DbContext 的正确方法

转载 作者:行者123 更新时间:2023-12-04 13:17:03 25 4
gpt4 key购买 nike

MiniProfiler site给出以下代码用于生成 Entity Framework ObjectContext :

public static MyModel Get()
{
var conn = new StackExchange.Profiling.Data.EFProfiledDbConnection(GetConnection(), MiniProfiler.Current);
return ObjectContextUtils.CreateObjectContext<MyModel>(conn); // resides in the MiniProfiler.EF nuget pack
}

但是,使用 Entity Framework 5,我没有使用 ObjectContext - 我使用的是 DbContext .我无法在此处插入型号名称,因为 CreateObjectContext<T>()方法期望 TObjectContext 类型. (出于同样的原因, this answer 中给出的代码也不起作用)。

此外,我正在使用 autofac 来初始化我的 Db 连接。这是通过以下方式注册的( MyData = 我的 EF DataContext 的名称):
Builder.RegisterType<MyData>().As<DbContext>().InstancePerHttpRequest();

所以结合两个部分:如何使用 autofac 来初始化绑定(bind)到 MiniProfiler.EF 的 DbContext?如果那不可能,至少我该怎么做第一部分(为 MiniProfiler.EF 创建工厂方法以返回 DbContext )?

最佳答案

我刚刚得到这个工作:

public static class DbContextUtils
{
private const BindingFlags PrivateInstance = BindingFlags.NonPublic | BindingFlags.Instance;

public static T CreateDbContext<T>() where T : DbContext
{
return CreateDbContext<T>(GetProfiledConnection<T>());
}

public static T CreateDbContext<T>(this DbConnection connection) where T : DbContext
{
var workspace = new MetadataWorkspace(new[] { "res://*/" }, new[] { typeof(T).Assembly });
var factory = DbProviderServices.GetProviderFactory(connection);

var itemCollection = workspace.GetItemCollection(DataSpace.SSpace);
var providerFactoryField = itemCollection.GetType().GetField("_providerFactory", PrivateInstance);
if (providerFactoryField != null) providerFactoryField.SetValue(itemCollection, factory);

var ec = new EntityConnection(workspace, connection);

return CtorCache<T, DbConnection>.Ctor(ec);
}

public static DbConnection GetProfiledConnection<T>() where T : DbContext
{
var dbConnection = ObjectContextUtils.GetStoreConnection("name=" + typeof(T).Name);
return new EFProfiledDbConnection(dbConnection, MiniProfiler.Current);
}

internal static class CtorCache<TType, TArg> where TType : class
{
public static readonly Func<TArg, TType> Ctor;
static CtorCache()
{
var argTypes = new[] { typeof(TArg) };
var ctor = typeof(TType).GetConstructor(argTypes);
if (ctor == null)
{
Ctor = x => { throw new InvalidOperationException("No suitable constructor defined"); };
}
else
{
var dm = new DynamicMethod("ctor", typeof(TType), argTypes);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Ret);
Ctor = (Func<TArg, TType>)dm.CreateDelegate(typeof(Func<TArg, TType>));
}
}
}
}

它基于 MiniProfiler's ObjectContextUtils 中的代码.

你像这样使用它:
builder.Register(c => DbContextUtils.CreateDbContext<MyData>()).As<DbContext>().InstancePerHttpRequest();

这个解决方案 需要 您的 DbContext有一个构造函数,它采用 DbConnection并将其传递给基地,如下所示:
public MyData(DbConnection connection)
: base(connection, true)
{
}

关于autofac - 使用 MiniProfiler 和 EF 5 和 Autofac 分析 DbContext 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13496557/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com