NLog与实体框架连接字符串?

时间:2012-02-03 21:04:05

标签: .net entity-framework connection-string nlog

我正在尝试使用'Database' NLog target并希望NLog读取我的连接字符串,以避免在同一配置文件中设置两次。问题是我有Entity Framework-style connection string,因此使用connectionStringName属性不起作用。

在log4net中,我可以使用custom AdoNetAppender并自己提取连接字符串的相应部分。有没有办法自定义NLog的数据库目标,所以我可以传入一个适当样式的连接字符串?

5 个答案:

答案 0 :(得分:7)

通过在代码中配置日志记录目标,可以轻松解决此问题:

    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依赖项或想要更完整的解决方案,那么您可以查看两个都有nuget包可用的NLog.MvcNLog.EntityFramework个存储库...

答案 1 :(得分:5)

无法自定义内置DatabaseTarget,因为它是sealed。 并且没有任何其他扩展点,因为DatabaseTarget.InitializeTarget()将始终抛出异常,因为它无法创建EF DbProviderFactory

providerName="System.Data.EntityClient"形式

因此,使用当前的NLog版本2.0.0.0,您必须遵循以下选项:

  1. 您可以复制连接字符串,也可以使用DatabaseTarget数据库配置属性。
  2. 您可以从头开始编写自己的custom target
  3. 您可以提交功能请求,并等待其实施。

答案 2 :(得分:1)

从DbContext获取正常连接字符串的方法如下:

context.Database.Connection.ConnectionString

假设你有适当格式的连接字符串,我认为像这样配置目标更容易:

1)在配置中定义目标

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

2)在运行时设置连接字符串

GlobalDiagnosticsContext.Set("myConnectionString", connectionString);

这样,您就不会硬编码数据库目标行为。

答案 3 :(得分:1)

NLog 4.5添加了对从Entity Framework解析连接字符串的支持,因此可以直接使用它们:

https://github.com/NLog/NLog/pull/2510

NLog DatabaseTarget也不再密封,因此,如果需要特殊处理,则也可以这样做。

进行特殊解析/查找逻辑的正常方法是注册一个自定义layoutrenderer并在ConnectionString-Layout中引用它:

https://github.com/NLog/NLog/wiki/How-to-write-a-custom-layout-renderer

答案 4 :(得分:0)

将变量添加到NLog.config文件中

<variable name="connectionStringNLog" value="" />

然后在目标元素中引用此变量

<target name="my-db"
        xsi:type="Database"
        dbProvider="System.Data.SqlClient"        
        connectionString="${var:connectionStringNLog}"
        commandType="StoredProcedure"
        commandText="[dbo].[LogEntryInsert]">

,然后在您的contextfactory c#文件中添加以下行以分配连接字符串值,无论它是来自其他配置文件还是来自Key Vault:

LogManager.Configuration.Variables["connectionStringNLog"] = conn.ConnectionString;
相关问题