如何正确分析entity framework?
为了从EF 4.1获得单个回调,我可以编写的最小代码量是多少,它提供了以下内容:
OnSQLExecuted(DbCommand cmd, DateTime start, double durationMS, string stacktrace)
目前我们使用的是令人讨厌的黑客攻击,这似乎是在泄露性能,我很好奇我们如何能够在对应用程序产生最小影响的情况下实现此回调。
我们可以通过黑客入侵 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().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上需要一些reflection黑客和完全炸弹:
FileLoadException: The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
Frans和Ayende都记录了这一点。
如何以健壮和优雅的方式连接我的剖析工厂和家庭?
有没有其他方法来获得我的回调?
最简单的方法是使用Entity Framework跟踪包装器并挂钩到EFTracingConnection
的CommandFinished
。 它没有给你开始时间,但它确实给你持续时间(从Now
减去,可能足够接近)。
我将代码影响称为“中等”,因为您必须更改对现有上下文类的引用。 不过,这很简单。
如果您只想跟踪并且不需要实际回调,则NuGet包具有简单的默认跟踪系统 。
编辑(添加了堆栈跟踪): EF跟踪包装器不会为您提供堆栈跟踪。 您可以获得源代码并添加它而不会有太多困难,但我认为这会影响性能。
虽然它是商业产品,但我也强烈建议您查看EF教授 。 这个工具是由Ayende(Oren Eini拼写?)开发的,他还创建了NH Prof,优步教授(NH + EF教授)和RavenDB等产品。
购买了他的NH教授,在调整NH时它是非常宝贵的,我希望EF教授分别同样有价值。
第一:如果您正在寻找自定义实现,您可以直接在EF中触发自己的事件而忘记它。 ADO.NET团队不知何故忘记实现任何扩展点,他们甚至忘记实现任何日志记录(除了将ObjectQuery
/ DbQuery
转换为SQL,但它不处理延迟加载或数据修改)。
我相信与EF一起使用的每个跟踪实现都是通过创建自定义DbProviderFactory
来完成的,它包装了真正的工厂并包装了真正的Connection
, Command
等。这在前面提到的跟踪包装器中已经非常清楚地描述了。
有商业工具已经做你想要的
- 提到EF教授是一个很好的工具,但每个座位花费300美元。
- 另一种选择是Huagati Query Profiler 。 特别是这个屏幕截图看起来像你在寻找。 价格低得多(每个座位40美元),它支持Linq-to-sql,Entity Framework和LLBLGen。
这两个工具都有免费试用版,因此您可以下载并试用它们。
顺便说一句。 如果您拥有VS 2010 Ultimate,也许您可以从Intelli Trace中获取大量信息。 您可以在MSDN杂志中阅读所有当前可用的替代方案。
我认为有一个很大的问号 – 你使用的是DbContext还是ObjectContext(你提到过EFv4.1)? 为ObjectContext API创建了提到的工具和跟踪包装器,因此我不确定它们如何与DbContext API一起使用。 您仍然可以从DbContext
获取ObjectContext
但如果该工具期望EntityConnection
而不是公共连接,那么这将是一个问题。
我可以推荐Entity Framework Profiler,每月订阅最适合您需要,每月最低费用为16美元。 我们在DbContext上遇到了一些性能问题,它提供了很好的视觉信息来解决这些问题。 您可以将EF Profiler与持续集成服务器集成,并不断提高性能。