2013-11-20 64 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

相關問題