2

我被分配了一个项目,其中 DAL 由一个基类组成,该基类具有返回 IDataReader、一个对象(int、字符串等)或一个数据集的函数。还存在一个 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);
    }
    ...
}

然后是调用 DAL 函数的 BLL 类,并根据从 IDataReader 对象读取的数据用数据填充对象(例如 Order 对象):

    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 对象并关闭连接将使阅读器无效。我有从 DAL 获取和使用 IDataReader 的所有代码都使用 using 语句,但是 SqlConnection 对象是否也在被释放,或者它是否在稍后阶段被 GC,通过不尽快释放连接池而损害连接池? 如果是这样,如何治疗?

此外,是否有比上述方法更好的方法来创建 DAL?我不太关心与数据存储无关的 DAL,我们只需要一个可靠且易于维护的 DAL,它可以从多个线程获取多个并发连接。

提前感谢您对此的任何帮助。

4

1 回答 1

4

SqlDataReaderCommandBehavior.CloseConnection如果您在执行命令时指定,将关闭连接。不过,总觉得有点难看。

相反,将 a 传递给SqlConnection 方法并使用它。然后调用者可以控制何时处理。或者,Action<SqlDataReader>使用打开的阅读器执行,并在执行操作后使该方法关闭阅读器和连接。当然,该操作必须对读者做所有需要做的事情。

于 2009-07-12T20:37:43.973 回答