2013-11-20 66 views
3

我在C#中创建DatabaseTarget对象并使用它将数据记录到NLog数据库中。在nlog中以编程方式创建数据库以启用使用DatabaseTarget

如果数据库不存在,则nlog目标失败。我想检查数据库是否存在,以及它是否不创建它和日志表。

我可以看到targetDB.Install(installationContext)函数似乎能够完成这项工作,但找不到任何示例。有很多使用配置文件的例子。我想把它放在代码中,而不必在所有使用包含此代码的DLL的应用程序中部署配置文件。

如何检查并创建数据库?

回答

5

此代码使用安装()方法,如果他们不这样做已经创建日志数据库和表存在:

private static void GetDBLogger(string strConnectionString) 
    { 
     StringBuilder sb = new StringBuilder(); 
     InstallationContext installationContext = new InstallationContext(); 

     SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); 
     builder.ConnectionString = strConnectionString; 
     string strDatabase = builder.InitialCatalog; 

     NLog.Targets.DatabaseTarget targetDB = new NLog.Targets.DatabaseTarget(); 

     targetDB.Name = "db"; 
     targetDB.ConnectionString = strConnectionString; 

     NLog.Targets.DatabaseParameterInfo paramDB; 

     paramDB = new NLog.Targets.DatabaseParameterInfo(); 
     paramDB.Name = string.Format("@Message"); 
     paramDB.Layout = string.Format("${{message}}"); 
     targetDB.Parameters.Add(paramDB); 
     targetDB.CommandText = string.Format("INSERT INTO Logs(Message) VALUES (@message);"); 

     // Keep original configuration 
     LoggingConfiguration config = LogManager.Configuration; 
     if (config == null) 
      config = new LoggingConfiguration(); 

     config.AddTarget(targetDB.Name, targetDB); 

     LoggingRule rule = new LoggingRule("*", LogLevel.Debug, targetDB); 
     config.LoggingRules.Add(rule); 

     LogManager.Configuration = config; 

     SqlConnectionStringBuilder builder2 = new SqlConnectionStringBuilder(); 
     builder2.ConnectionString = strConnectionString; 
     builder2.InitialCatalog = "master"; 

     // we have to connect to master in order to do the install because the DB may not exist 
     targetDB.InstallConnectionString = builder2.ConnectionString; 

     sb.AppendLine(string.Format("IF NOT EXISTS (SELECT name FROM master.sys.databases WHERE name = N'{0}')", strDatabase)); 
     sb.AppendLine(string.Format("CREATE DATABASE {0}", strDatabase)); 

     DatabaseCommandInfo createDBCommand = new DatabaseCommandInfo(); 
     createDBCommand.Text = sb.ToString(); 
     createDBCommand.CommandType = System.Data.CommandType.Text; 
     targetDB.InstallDdlCommands.Add(createDBCommand); 

     // create the database if it does not exist 
     targetDB.Install(installationContext); 

     targetDB.InstallDdlCommands.Clear(); 
     sb.Clear(); 
     sb.AppendLine("IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'Logs')"); 
     sb.AppendLine("RETURN"); 
     sb.AppendLine(""); 
     sb.AppendLine("CREATE TABLE [dbo].[Logs]("); 
     sb.AppendLine("[LogId] [int] IDENTITY(1,1) NOT NULL,"); 
     sb.AppendLine("[Message] [nvarchar](max) NULL,"); 
     sb.AppendLine(" CONSTRAINT [PK_Logs] PRIMARY KEY CLUSTERED "); 
     sb.AppendLine("("); 
     sb.AppendLine("[LogId] ASC"); 
     sb.AppendLine(")WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]"); 
     sb.AppendLine(") ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]"); 

     DatabaseCommandInfo createTableCommand = new DatabaseCommandInfo(); 
     createTableCommand.Text = sb.ToString(); 
     createTableCommand.CommandType = System.Data.CommandType.Text; 
     targetDB.InstallDdlCommands.Add(createTableCommand); 

     // we can now connect to the target DB 
     targetDB.InstallConnectionString = strConnectionString; 

     // create the table if it does not exist 
     targetDB.Install(installationContext); 
    } 
+1

真棒,我不知道该SqlConnectionStringBuilder可以反向使用这样的。正如顾名思义,我总是使用它。 – Jakotheshadows

+0

我有类似的问题,但是你的代码不工作我的我得到一个'ArgumentNullException'说,一个*类型参数不能为null *从堆栈跟踪它看起来在这里:' 在System.Activator .CreateInstance(Type type,Boolean nonPublic) at System.Activator.CreateInstance(Type type) at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString)' 任何想法为什么会这样? – Luiso

相关问题