DataProvider不等于SQLHelper

微软企业库可用来做ORM,其数据层核心是DataProvider,类似常用的SQLHelper,但这仅仅只是类似而已。以下是其反编后的代码:

	public class DataProvider
	{
		public string ConnectionString = string.Empty;
		private SqlConnection DbConnection = null;
		private SqlCommand DbCommand = null;
		private SqlTransaction DbTransaction = null;
		[MethodImpl(MethodImplOptions.NoInlining)]
		private void Open()
		{
			if (this.DbConnection == null)
			{
				this.DbConnection = new SqlConnection(this.ConnectionString);
			}
			if (!this.DbConnection.State.Equals(ConnectionState.Open))
			{
				this.DbConnection.Open();
			}
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public void Close()
		{
			if (this.DbConnection != null)
			{
				if (this.DbConnection.State.Equals(ConnectionState.Open))
				{
					this.Rollback();
					this.DbConnection.Close();
				}
				if (this.DbCommand != null)
				{
					this.DbCommand.Dispose();
					this.DbCommand = null;
				}
				this.DbConnection.Dispose();
				this.DbConnection = null;
			}
		}
		private void CreateCommand()
		{
			this.Open();
			if (this.DbCommand == null)
			{
				this.DbCommand = this.DbConnection.CreateCommand();
				this.DbCommand.CommandTimeout = 180;
			}
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public void BeginTransaction()
		{
			this.CreateCommand();
			this.DbTransaction = this.DbConnection.BeginTransaction();
			this.DbCommand.Transaction = this.DbTransaction;
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public void Commit()
		{
			if (this.DbTransaction != null)
			{
				this.DbTransaction.Commit();
				this.DbTransaction.Dispose();
				this.DbTransaction = null;
			}
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public void Rollback()
		{
			if (this.DbTransaction != null)
			{
				this.DbTransaction.Rollback();
				this.DbTransaction.Dispose();
				this.DbTransaction = null;
			}
		}
		public int ExecuteNonQuery(string SQL, CommandType type)
		{
			this.CreateCommand();
			this.DbCommand.CommandText = SQL;
			this.DbCommand.CommandType = type;
			return this.DbCommand.ExecuteNonQuery();
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public DataSet ExecuteDataSet(string SQL, CommandType type)
		{
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
			DataSet result;
			try
			{
				this.CreateCommand();
				this.DbCommand.CommandText = SQL;
				this.DbCommand.CommandType = type;
				sqlDataAdapter = new SqlDataAdapter(this.DbCommand);
				DataSet dataSet = new DataSet();
				sqlDataAdapter.Fill(dataSet);
				result = dataSet;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (sqlDataAdapter != null)
				{
					sqlDataAdapter.Dispose();
				}
			}
			return result;
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public DataTable ExecutedProcedure(string strProcedureName, SqlParameter[] parameters)
		{
			SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
			DataTable result;
			try
			{
				this.CreateCommand();
				this.DbCommand.CommandText = strProcedureName;
				this.DbCommand.CommandType = CommandType.StoredProcedure;
				if (parameters != null)
				{
					for (int i = 0; i < parameters.Length; i++)
					{
						this.DbCommand.Parameters.Add(parameters[i]);
					}
				}
				sqlDataAdapter = new SqlDataAdapter(this.DbCommand);
				DataSet dataSet = new DataSet();
				sqlDataAdapter.Fill(dataSet);
				result = dataSet.Tables[0];
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (sqlDataAdapter != null)
				{
					sqlDataAdapter.Dispose();
				}
			}
			return result;
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public DataTable ExecuteDataTable(string SQL, CommandType type)
		{
			DataSet dataSet = this.ExecuteDataSet(SQL, type);
			DataTable result;
			if (dataSet == null || dataSet.Tables.Count <= 0)
			{
				result = null;
			}
			else
			{
				result = dataSet.Tables[0];
			}
			return result;
		}
		[MethodImpl(MethodImplOptions.NoInlining)]
		public string ExecuteScalar(string sql, CommandType type, SqlParameter[] parameters)
		{
			string result = string.Empty;
			try
			{
				this.CreateCommand();
				this.DbCommand.CommandText = sql;
				this.DbCommand.CommandType = type;
				if (parameters != null)
				{
					for (int i = 0; i < parameters.Length; i++)
					{
						this.DbCommand.Parameters.Add(parameters[i]);
					}
				}
				object obj = this.DbCommand.ExecuteScalar();
				if (obj != null)
				{
					result = obj.ToString();
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
			return result;
		}
	}

所有的执行方法都是只有打开执行,没有用using,也没有在方法体内关闭连接,那么问题来了,如果像sqlhelper一样的调用它的话,那么数据库将会建立很多连接,一直到你的限制数(webconfig中设置的Max Pool Size=200),然后异常。

可以通过sql性能工具看到当前的ExistingConnection,如果不关闭,每一次刷新,都会多几个连接。

关于ExistingConnection,msdn

另一个可以通过Windows的性能计数器看到,执行一次业务数据,线陡然上升一次。。。。

DataProvider不等于SQLHelper_第1张图片

当然连接最终是可以回收的,但需要时间很长。

由于数据层用了企业库,而又确实要调用这个类,目前想到以下两种方法:

1、所有的CRUD都要记得显式关闭连接。

2、可以封装一个单例模式或者写成静态类,所有的业务层都要调用同一个类的方法。

你可能感兴趣的:(数据库)