【发布时间】:2011-07-07 15:36:29
【问题描述】:
为了从 EF 4.1 获取单个回调,我可以编写的最少代码量是多少,该回调提供以下内容:
-
OnSQLExecuted(DbCommand cmd, DateTime start, double durationMS, string stacktrace)
目前我们使用了一种似乎会导致性能泄漏的令人讨厌的 hack,我很好奇我们如何才能在对应用程序影响最小的情况下实现此回调。
我们可以通过hacking around 将其连接到Mini Profiler - 最初我们更改了Database.DefaultConnectionFactory 但是使用默认工厂意味着您不能同时拥有两个分析工厂。所以我们走的是更激进的路线。
通常使用的技术非常简单,您可以实现:DbProviderFactory、IDbConnectionFactory、DbProviderServices、DbConnection、DbCommand 和 DbDataReader,以便它们拦截调用和配置文件。
到目前为止,很容易......但是当您尝试连接时它会变得混乱:
try
{
// ensure all the factories are loaded
DbProviderFactories.GetFactory("...");
}
catch (ArgumentException)
{
}
Type type = typeof(DbProviderFactories);
DataTable table;
// SUPER UGLY - Can this be done in another way?
object setOrTable = (type.GetField("_configTable", BindingFlags.NonPublic | BindingFlags.Static) ??
type.GetField("_providerTable", BindingFlags.NonPublic | BindingFlags.Static)).GetValue(null);
if (setOrTable is DataSet)
{
table = ((DataSet)setOrTable).Tables["DbProviderFactories"];
}
table = (DataTable)setOrTable;
foreach (DataRow row in table.Rows.Cast<DataRow>().ToList())
{
DbProviderFactory factory;
try
{
factory = DbProviderFactories.GetFactory(row);
}
catch (Exception)
{
continue;
}
var profType = typeof(MvcMiniProfiler.Data.EFProfiledDbProviderFactory<>).MakeGenericType(factory.GetType());
DataRow profiled = table.NewRow();
profiled["Name"] = row["Name"];
profiled["Description"] = row["Description"];
profiled["InvariantName"] = row["InvariantName"];
profiled["AssemblyQualifiedName"] = profType.AssemblyQualifiedName;
table.Rows.Remove(row);
table.Rows.Add(profiled);
}
在最新版本的 EF 上需要一些反射技巧和完全炸弹:
FileLoadException: The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
如何以稳健而优雅的方式连接我的分析工厂和家庭?
有没有其他方法可以得到我的回调?
【问题讨论】:
标签: c# .net entity-framework entity-framework-4