⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adonetappender.cs

📁 精通SQL Server2005项目开发
💻 CS
📖 第 1 页 / 共 3 页
字号:
			InitializeDatabaseCommand();
		}

		#endregion

		#region Override implementation of AppenderSkeleton

		/// <summary>
		/// Override the parent method to close the database
		/// </summary>
		/// <remarks>
		/// <para>
		/// Closes the database command and database connection.
		/// </para>
		/// </remarks>
		override protected void OnClose() 
		{
			base.OnClose();

			// Close the cached command and connection objects
			if (m_dbCommand != null)
			{
				try
				{
					m_dbCommand.Dispose();
				}
				catch (Exception ex)
				{
					LogLog.Warn("AdoNetAppender: Exception while disposing cached command object", ex);
				}
				m_dbCommand = null;
			}
			if (m_dbConnection != null)
			{
				try
				{
					m_dbConnection.Close();
				}
				catch (Exception ex)
				{
					LogLog.Warn("AdoNetAppender: Exception while disposing cached connection object", ex);
				}
				m_dbConnection = null;
			}
		}

		#endregion

		#region Override implementation of BufferingAppenderSkeleton

		/// <summary>
		/// Inserts the events into the database.
		/// </summary>
		/// <param name="events">The events to insert into the database.</param>
		/// <remarks>
		/// <para>
		/// Insert all the events specified in the <paramref name="events"/>
		/// array into the database.
		/// </para>
		/// </remarks>
		override protected void SendBuffer(LoggingEvent[] events)
		{
			if (m_reconnectOnError && (m_dbConnection == null || m_dbConnection.State != ConnectionState.Open))
			{
				LogLog.Debug("AdoNetAppender: Attempting to reconnect to database. Current Connection State: " + ((m_dbConnection==null)?"<null>":m_dbConnection.State.ToString()) );

				InitializeDatabaseConnection();
				InitializeDatabaseCommand();
			}

			// Check that the connection exists and is open
			if (m_dbConnection != null && m_dbConnection.State == ConnectionState.Open)
			{
				if (m_useTransactions)
				{
					// Create transaction
					// NJC - Do this on 2 lines because it can confuse the debugger
					IDbTransaction dbTran = null;
					try
					{
						dbTran = m_dbConnection.BeginTransaction();

						SendBuffer(dbTran, events);

						// commit transaction
						dbTran.Commit();
					}
					catch(Exception ex)
					{
						// rollback the transaction
						if (dbTran != null)
						{
							try
							{
								dbTran.Rollback();
							}
							catch(Exception)
							{
								// Ignore exception
							}
						}

						// Can't insert into the database. That's a bad thing
						ErrorHandler.Error("Exception while writing to database", ex);
					}
				}
				else
				{
					// Send without transaction
					SendBuffer(null, events);
				}
			}
		}

		#endregion // Override implementation of BufferingAppenderSkeleton

		#region Public Instance Methods

		/// <summary>
		/// Adds a parameter to the command.
		/// </summary>
		/// <param name="parameter">The parameter to add to the command.</param>
		/// <remarks>
		/// <para>
		/// Adds a parameter to the ordered list of command parameters.
		/// </para>
		/// </remarks>
		public void AddParameter(AdoNetAppenderParameter parameter)
		{
			m_parameters.Add(parameter);
		}


		#endregion // Public Instance Methods

		#region Protected Instance Methods

		/// <summary>
		/// Writes the events to the database using the transaction specified.
		/// </summary>
		/// <param name="dbTran">The transaction that the events will be executed under.</param>
		/// <param name="events">The array of events to insert into the database.</param>
		/// <remarks>
		/// <para>
		/// The transaction argument can be <c>null</c> if the appender has been
		/// configured not to use transactions. See <see cref="UseTransactions"/>
		/// property for more information.
		/// </para>
		/// </remarks>
		virtual protected void SendBuffer(IDbTransaction dbTran, LoggingEvent[] events)
		{
			if (m_usePreparedCommand) 
			{
				// Send buffer using the prepared command object

				if (m_dbCommand != null)
				{
					if (dbTran != null)
					{
						m_dbCommand.Transaction = dbTran;
					}

					// run for all events
					foreach(LoggingEvent e in events)
					{
						// Set the parameter values
						foreach(AdoNetAppenderParameter param in m_parameters)
						{
							param.FormatValue(m_dbCommand, e);
						}

						// Execute the query
						m_dbCommand.ExecuteNonQuery();
					}
				}
			}
			else
			{
				// create a new command
				using(IDbCommand dbCmd = m_dbConnection.CreateCommand())
				{
					if (dbTran != null)
					{
						dbCmd.Transaction = dbTran;
					}

					// run for all events
					foreach(LoggingEvent e in events)
					{
						// Get the command text from the Layout
						string logStatement = GetLogStatement(e);

						LogLog.Debug("AdoNetAppender: LogStatement ["+logStatement+"]");

						dbCmd.CommandText = logStatement;
						dbCmd.ExecuteNonQuery();
					}
				}
			}
		}

		/// <summary>
		/// Formats the log message into database statement text.
		/// </summary>
		/// <param name="logEvent">The event being logged.</param>
		/// <remarks>
		/// This method can be overridden by subclasses to provide 
		/// more control over the format of the database statement.
		/// </remarks>
		/// <returns>
		/// Text that can be passed to a <see cref="System.Data.IDbCommand"/>.
		/// </returns>
		virtual protected string GetLogStatement(LoggingEvent logEvent)
		{
			if (Layout == null)
			{
				ErrorHandler.Error("ADOAppender: No Layout specified.");
				return "";
			}
			else
			{
				StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
				Layout.Format(writer, logEvent);
				return writer.ToString();
			}
		}

		/// <summary>
		/// Connects to the database.
		/// </summary>		
		private void InitializeDatabaseConnection()
		{
			try
			{
				// Cleanup any existing command or connection
				if (m_dbCommand != null)
				{
					try
					{
						m_dbCommand.Dispose();
					}
					catch (Exception ex)
					{
						LogLog.Warn("AdoNetAppender: Exception while disposing cached command object", ex);
					}
					m_dbCommand = null;
				}
				if (m_dbConnection != null)
				{
					try
					{
						m_dbConnection.Close();
					}
					catch (Exception ex)
					{
						LogLog.Warn("AdoNetAppender: Exception while disposing cached connection object", ex);
					}
					m_dbConnection = null;
				}

				// Create the connection object
				m_dbConnection = (IDbConnection)Activator.CreateInstance(ResolveConnectionType());
			
				// Set the connection string
				m_dbConnection.ConnectionString = m_connectionString;

				using(SecurityContext.Impersonate(this))
				{
					// Open the database connection
					m_dbConnection.Open();
				}
			}
			catch (System.Exception e)
			{
				// Sadly, your connection string is bad.
				ErrorHandler.Error("Could not open database connection [" + m_connectionString + "]", e);
	 
				m_dbConnection = null;
			}
		}

		/// <summary>
		/// Retrieves the class type of the ADO.NET provider.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Gets the Type of the ADO.NET provider to use to connect to the
		/// database. This method resolves the type specified in the 
		/// <see cref="ConnectionType"/> property.
		/// </para>
		/// <para>
		/// Subclasses can override this method to return a different type
		/// if necessary.
		/// </para>
		/// </remarks>
		/// <returns>The <see cref="Type"/> of the ADO.NET provider</returns>
		virtual protected Type ResolveConnectionType()
		{
			try
			{
				return SystemInfo.GetTypeFromString(m_connectionType, true, false);
			}
			catch(Exception ex)
			{
				ErrorHandler.Error("Failed to load connection type ["+m_connectionType+"]", ex);
				throw;
			}
		}

		/// <summary>
		/// Prepares the database command and initialize the parameters.
		/// </summary>
		private void InitializeDatabaseCommand()
		{
			if (m_dbConnection != null && m_usePreparedCommand)
			{
				try
				{
					// Cleanup any existing command or connection
					if (m_dbCommand != null)
					{
						try
						{
							m_dbCommand.Dispose();
						}
						catch (Exception ex)
						{
							LogLog.Warn("AdoNetAppender: Exception while disposing cached command object", ex);
						}
						m_dbCommand = null;
					}

					// Create the command object
					m_dbCommand = m_dbConnection.CreateCommand();
		
					// Set the command string
					m_dbCommand.CommandText = m_commandText;

					// Set the command type
					m_dbCommand.CommandType = m_commandType;
				}
				catch(System.Exception e)
				{
					ErrorHandler.Error("Could not create database command ["+m_commandText+"]", e);	 

					if (m_dbCommand != null)
					{
						try
						{
							m_dbCommand.Dispose();
						}
						catch
						{
							// Ignore exception
						}
						m_dbCommand = null;
					}
				}

				if (m_dbCommand != null)
				{
					try
					{
						foreach(AdoNetAppenderParameter param in m_parameters)
						{
							try
							{
								param.Prepare(m_dbCommand);
							}
							catch(System.Exception e)
							{
								ErrorHandler.Error("Could not add database command parameter ["+param.ParameterName+"]", e);	 
								throw;
							}
						}
					}
					catch
					{
						try
						{
							m_dbCommand.Dispose();
						}
						catch
						{
							// Ignore exception
						}
						m_dbCommand = null;
					}
				}

				if (m_dbCommand != null)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -