Я использую Entity Framework 6, и это потрясающие функции перехватчика базы данных для регистрации запросов, которые отправляются из приложения в базу данных. Однако я изо всех сил пытаюсь рассчитать время для этих запросов, у меня есть длительный запрос, который возвращает от сотен тысяч до миллионов строк, поэтому он занимает от 6 до 15 секунд в зависимости от объема данных, которые этот запрос собирается вернуть. Entity framework возвращает SqlDataReader, из-за чего я не могу узнать точное время, необходимое для получения результата. Я хочу знать полное время выполнения с момента отправки запроса до времени чтения последней строки. Есть способ сделать это.
Вот регистратор, который я обычно использую для EF.
public class EFLoggerForTesting : IDbCommandInterceptor
{
static readonly ConcurrentDictionary<DbCommand, DateTime> m_StartTime = new ConcurrentDictionary<DbCommand, DateTime>();
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
Log(command, interceptionContext);
}
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
Log(command, interceptionContext);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
Log(command, interceptionContext);
}
private static void Log<T>(DbCommand command, DbCommandInterceptionContext<T> interceptionContext)
{
DateTime startTime;
TimeSpan duration;
if (m_StartTime.TryRemove(command, out startTime))
{
duration = DateTime.Now - startTime;
}
else
duration = TimeSpan.Zero;
var requestId =-1;
string message;
var parameters = new StringBuilder();
foreach (DbParameter param in command.Parameters)
{
parameters.AppendLine(param.ParameterName + " " + param.DbType + " = " + param.Value);
}
if (interceptionContext.Exception == null)
{
message = string.Format("Database call took {0} sec. RequestId {1} \r\nCommand:\r\n{2}", duration.TotalSeconds.ToString("N3"), requestId, parameters.ToString() + command.CommandText);
}
else
{
message = string.Format("EF Database call failed after {0} sec. RequestId {1} \r\nCommand:\r\n{2}\r\nError:{3} ", duration.TotalSeconds.ToString("N3"), requestId, parameters.ToString() + command.CommandText, interceptionContext.Exception);
}
Debug.WriteLine(message);
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
OnStart(command);
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
OnStart(command);
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
OnStart(command);
}
private static void OnStart(DbCommand command)
{
m_StartTime.TryAdd(command, DateTime.Now);
}
}
К сожалению, документации не существует, поэтому я не знаю, сработает ли это для вашего сценария.
Эта статья взята из Интернета, укажите источник при перепечатке.
Если есть какие-либо нарушения, пожалуйста, свяжитесь с[email protected] Удалить.
я говорю два предложения