Я был назначен на проект, где DAL состоит из базового класса с функциями для возврата IDataReader, Object (int, string и т. П.) Или DataSet. Функция ExecuteNonQuery также существует. Этот DAL обращается только к USP (SQL Server) и использует MS SqlHelper для выполнения запросов. Вот две примеры функций из базы:
protected IDataReader ExecuteReader(string storedProcedure, params object[] parameterValues)
{
SqlConnection HConnection = new SqlConnection(myConnString);
IDataReader ret = null;
try
{
ret = SqlHelper.ExecuteReader(HConnection, storedProcedure, parameterValues);
}
catch (Exception ex)
{
HanldeError(ex, storedProcedure, parameterValues);
}
return ret;
}
protected object ExecuteScalar(string storedProcedure, params object[] parameterValues)
{
using (SqlConnection HConnection = new SqlConnection(myConnString))
{
object ret = null;
try
{
ret = SqlHelper.ExecuteScalar(HConnection, storedProcedure, parameterValues);
}
catch (Exception ex)
{
HanldeError(ex, storedProcedure, parameterValues);
}
return ret;
}
}
Другие классы являются производными от этого базового класса, создавая классы DAL для конкретных задач, например:
public class Orders : BaseDal {
public IDataReader GetOrdersList(int clientId, int agentId)
{
return ExecuteReader("usp_Orders_GetOrdersList", clientId, agentId);
}
...
}
Затем существуют классы BLL, которые вызывают функции DAL и заполняют объекты (например, объект Order) данными на основе данных, считанных из объекта IDataReader:
public Order[] GetOrdersList(int ClientIDX, int AgentIDX)
{
List<Order> ret = null;
using (IDataReader dr = objDAL.GetOrdersList(ClientIDX, AgentIDX))
{
if (dr != null)
{
ret = new List<Order>();
while (dr.Read())
{
ret.Add(xReadOrder(dr, 0));
}
}
}
return ret.ToArray();
}
У меня такой вопрос: если вы посмотрите на код, взятый из BaseDal, вы заметите, что только ExecuteScalar фактически завершает объект SqlConnection (оператор using) - так обстоит дело со всеми моими функциями. С ExecuteReader я не могу этого сделать, так как я возвращаю открытый объект SqlDataReader и закрытие соединения сделает недействительным считыватель.
У меня есть весь код, получающий и использующий IDataReader из DAL, использующий оператор using, но является ли объект SqlConnection также удаляемым или GC'-монтируется на более поздней стадии, повреждая пул соединений, не освобождая его раньше ? Если да, то как это можно лечить?
Кроме того, существует ли лучший подход к созданию DAL, чем описанный выше? Меня меньше беспокоит независимость DAL от хранилища данных, нам нужен только надежный и простой в обслуживании один, который может принимать много одновременных соединений из множества потоков.
Заранее спасибо за любую помощь в этом.