Можно ли настроить перехватчик еще в EntityFramework Core 1.0 rc2?
В платформе сущностей 6, как показано в этом сообщении, есть способ настроить перехватчик, который может регистрировать все медленные запросы, включая обратную трассировку стека.
Вопрос от 2015 года о более ранней бета-версии того, что тогда называлось EF7, говорит о том, что это не было возможно в ранних бета-версиях asp.net.
Тем не менее, весь дизайн EF Core должен быть компонуемым, и в обсуждениях по github bug tracker здесь можно использовать технику, когда вы создаете подкласс некоторого низкоуровневого класса, такого как SqlServerConnection
и затем переопределите некоторый метод там, чтобы получить некоторые точки, которые вы могли бы подключить до и после выполнения запроса, и добавить некоторое низкоуровневое ведение журнала, если было выполнено значение таймера в миллисекундах.
Это все еще необходимо и является единственной техникой в EF Core 1.0.0-rc2-final (по состоянию на июнь 2016 года)?
1 ответ
У EF Core пока нет "перехватчиков" или подобных хуков жизненного цикла. Эта функция отслеживается здесь: https://github.com/aspnet/EntityFramework/issues/626.
Переопределение низкоуровневого компонента может быть ненужным, если все, что вам нужно, это вывод журнала. Многие низкоуровневые компоненты EF Core уже производят ведение журналов, ведение журналов, включая выполнение запросов. Вы можете настроить EF для использования собственной фабрики логгеров, вызвав DbContextOptionsBuilder.UseLoggerFactory(ILoggerFactory factory)
, (См. https://docs.asp.net/en/latest/fundamentals/logging.html и https://github.com/aspnet/Logging для получения дополнительной информации об этом интерфейсе регистратора.) EF Core создает некоторые заметные события журнала с четко определить идентификаторы событий. (Увидеть Microsoft.EntityFrameworkCore.Infrastructure.CoreLoggingEventId
в 1.0.0-RC2, который был переименован в простоMicrosoft.EntityFrameworkCore.Infrastructure.CoreEventId
для 1.0.0 RTM.) См. https://docs.efproject.net/en/latest/miscellaneous/logging.html примеры того, как это сделать.
Если вам требуется дополнительная регистрация, выходящая за пределы того, что компоненты EF Core уже производят, вам придется переопределить компоненты более низкого уровня EF Core. Это лучше всего сделать путем переопределения существующего компонента и добавления этой переопределенной версии в EF посредством внедрения зависимостей. Для этого необходимо настроить собственного поставщика услуг для внутреннего использования EF. Это настраивается DbContextOptionsBuilder.UseInternalServiceProvider(IServiceProvider services)
См. https://docs.efproject.net/en/latest/miscellaneous/internals/services.html для получения дополнительной информации о том, как EF использует сервисы внутри компании.
Вот пример на github от ajcvickers о том, как использовать перехватчик в EF CORE (2.2 на момент ответа на этот вопрос):
public class NoLockInterceptor : IObserver<KeyValuePair<string, object>>
{
public void OnCompleted()
{
}
public void OnError(Exception error)
{
}
public void OnNext(KeyValuePair<string, object> value)
{
if (value.Key == RelationalEventId.CommandExecuting.Name)
{
var command = ((CommandEventData)value.Value).Command;
// Do command.CommandText manipulation here
}
}
}
Затем создайте глобальный слушатель для диагностики EF. Что-то вроде:
public class EfGlobalListener : IObserver<DiagnosticListener>
{
private readonly NoLockInterceptor _noLockInterceptor = new NoLockInterceptor();
public void OnCompleted()
{
}
public void OnError(Exception error)
{
}
public void OnNext(DiagnosticListener listener)
{
if (listener.Name == DbLoggerCategory.Name)
{
listener.Subscribe(_noLockInterceptor);
}
}
}
И зарегистрируйте это как часть запуска приложения:
DiagnosticListener.AllListeners.Subscribe(new EfGlobalListener());
It is coming for EntityFramework Core 3.0: https://github.com/aspnet/EntityFrameworkCore/issues/15066
It will work the same way as the one in EF 6