IDbCommandInterceptor 的实施似乎在我们的生产服务器上造成了令人难以置信的高工作负载(从 +-20% 到 +80%)。
有趣的是拦截过程中什么也没做。第一个想法是向 Entity Framework 生成的 SQL 添加跟踪,这样我们就可以轻松地在监视工具中跟踪哪个操作创建了 SQL。这是通过将调用堆栈的一部分作为注释添加到 SQL 中来完成的,但这似乎会导致服务器上的极端工作负载,因此代码被放在注释中,留下一个空类,如下所示。
我没有从上下文中删除拦截器,因为我认为它不会有任何影响,但显然它有。有谁知道为什么这会产生如此巨大的影响?
public class EntitiesDbInterceptor: IDbCommandInterceptor
{
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
AddSourceTracingToSqlQuery(command);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
AddSourceTracingToSqlQuery(command);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
AddSourceTracingToSqlQuery(command);
}
private void AddSourceTracingToSqlQuery(DbCommand dbCommand)
{
//try
//{
// var builder = new StringBuilder();
// var stack = new StackTrace(true);
// builder.Append("\r\n\r\n/********************* \r\n\r\n Entity Framework source trace: \r\n\r\n * ");
// var formattedStackTrace = string.Join("\r\n * ",
// from f in stack.GetFrames().Skip(2)
// let m = f?.GetMethod()
// where f?.GetFileLineNumber() != 0
// select m?.DeclaringType?.Name + "." + m?.Name + ":" + f?.GetFileLineNumber()
// );
// builder.Append(formattedStackTrace);
// builder.Append("\r\n*********************/\r\n\r\n");
// dbCommand.CommandText = builder.ToString() + dbCommand.CommandText;
//}
//catch (Exception)
//{
// throw;
//}
}
}
我们有同样的问题。 使用拦截器每个软件都会增加 cp 的使用大约 X4 倍。 唯一的解决方案是只在我们真正知道需要使用拦截器的操作中使用拦截器。
public DevEntities(string connectionstring, bool useInterceptor )
: base(connectionstring)
{
if(useInterceptor )
{
DbInterception.Add(new CommandInterceptor());
}
}