NLog со строкой подключения Entity Framework?


Я пытаюсь использовать 'Database' NLog target и хотел бы, чтобы NLog прочитал мою строку подключения, чтобы избежать необходимости устанавливать ее дважды в одном файле конфигурации. Проблема в том, что у меня есть строка соединения в стиле Entity Framework , поэтому использование атрибута connectionStringName не работает.

В log4net я могу использовать пользовательский AdoNetAppender и самостоятельно извлекать соответствующие фрагменты строки подключения. Есть ли какой-либо способ настроить цель базы данных NLog, чтобы я мог войти строка подключения в соответствующем стиле?

3 5

3 ответа:

Эта проблема может быть легко решена путем настройки цели ведения журнала в коде:

    private DatabaseTarget CreateDatabaseTarget()
    {
        var entityFrameworkConnection = ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString;
        var builder = new EntityConnectionStringBuilder(entityFrameworkConnection);
        var connectionString = builder.ProviderConnectionString;

        var target = new DatabaseTarget()
        {
            ConnectionString = connectionString,
            CommandText = @"insert into Log ([DateTime], [Message]) values (@dateTime, @message);",
            Parameters = {
                new DatabaseParameterInfo("@dateTime", new NLog.Layouts.SimpleLayout("${date}")), 
                new DatabaseParameterInfo("@message", new NLog.Layouts.SimpleLayout("${message}")), 
           }
        };
        return target;
    }

Затем вы можете зарегистрировать его с помощью конфигурации NLog:

var target = CreateDatabaseTarget();
LogManager.Configuration.AddTarget("databaseTarget", CreateDatabaseTarget());
LogManager.Configuration.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Warn, target));
Но если вы согласны с некоторыми зависимостями Nuget или хотите получить более полное решение, вы можете взглянуть на NLog.Mvc и NLog.EntityFramework репозитории, в которых доступны пакеты nuget...

Нет способа настроить встроенный DatabaseTarget, потому что это sealed. И нет никаких других точек расширения, потому что DatabaseTarget.InitializeTarget() всегда будет выдавать исключение, потому что он не может создать DbProviderFactory форму EF providerName="System.Data.EntityClient"

Итак, с текущей версией NLog 2.0.0.0 у вас есть следующие опции:

  1. можно дублировать строку подключения или использовать атрибуты конфигурации базы данныхDatabaseTarget .
  2. вы можете написать свой собственный пользовательский целевой объект в основном с нуля.
  3. вы можете отправить запрос на функцию и подождать, пока он будет реализован.

Способ получить нормальную строку соединения из DbContext следующий:

context.Database.Connection.ConnectionString

Предполагая, что у вас есть строка подключения в соответствующем формате, я думаю, что проще настроить цель следующим образом:

1) Определите цель в вашей конфигурации

 <target name="database" type="Database" connectionString="${gdc:myConnectionString}">
    <commandText>
      ...
    </commandText>

2) Установите строку подключения во время выполнения

GlobalDiagnosticsContext.Set("myConnectionString", connectionString);

Таким образом, вы не жестко задаете поведение целевой базы данных.