我们有一个SQL实用程序类,它将存储过程的名称作为其输入参数,并以datatable形式返回结果。这背后的原因是我们不必担心忘记关闭连接和连接泄漏。此外,我们可以通过不必在数据访问层中重新创建数据适配器和数据引导来减少代码。
我遇到的问题是我们正在填充一个数据表,以便我们可以遍历它来创建我们的对象,所以我们基本上像一个datareader一样使用它。我已经读过将返回datareader或dataadapter的类。但问题是客户端必须打开和关闭连接,或者您必须在Finalize方法中关闭连接。您似乎不希望垃圾收集负责关闭数据库连接。
总而言之,我们希望有一个类,这样我们就可以通过不必为每个查询创建数据引导来减少代码,从而确保数据库连接被关闭。
处理此问题的最佳方法是什么?
更新:还在考虑这个问题,但到目前为止,最佳做法似乎仍然是返回一个datareader,使用CommandBehavior.CloseConnection,然后信任谁曾使用该类调用dr。关闭()?
答案 0 :(得分:3)
您是否考虑过Microsoft Enterprise Library?
public List<User> GetUsers()
{
List<User> result = new List<User>();
Database db = new
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(this.connectionString);
DbCommand cmd = db.GetStoredProcCommand("GetUsers");
using (IDataReader rdr = db.ExecuteReader(cmd))
{
while (rdr.Read())
{
User user = new User();
FillUser(rdr, user);
result.Add(user);
}
}
return result;
}
答案 1 :(得分:2)
我们使用这样的东西,它在高音量下表现很好。
public SqlDataReader ExecuteReader(string command, SqlParameter[] parameters)
{
SqlDataReader reader = null;
using (SqlConnection conn = new SqlConnection())
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = command;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters);
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
return reader;
}
DataTables不被认为是最佳做法,原因有多种,包括其膨胀和缺乏类型安全性。
答案 2 :(得分:1)
我有相同的结构 - 实用程序类,其方法可以获取数据并返回填充的DataTable(或填充/更新传入其中的DataTable) - 原因完全相同:保持数据库连接与其余部分分开代码并确保它们仅在需要时关闭并尽快关闭。特别是因为数据存储在各种后端系统中,我想只向我的应用程序提供一个接口,而不用担心细节。
您的情况有一个区别:我们(通常)不会从DataTables中的行创建对象,而是直接处理行中的数据。我发现使用DataTables简单而有效。
除此之外,我个人认为这种方法没有任何问题,并且发现它对我们的目的非常有效。
答案 3 :(得分:0)
返回datareader在很多场景中都不起作用。在很多地方,生产中不允许从客户端机器直接连接到数据库(有充分理由)。因此,您必须序列化要检索的对象。我可以想到一些设计可以让你在服务器端用于远程处理/序列化的任何类中坚持使用datareader,但是通过痛苦的行方式在http或nettcp中返回项目可能不会带来太多好处。
您是否在序列化这些对象?如果是这样,您的选择将归结为Datatable,Dataset或自定义对象。自定义对象,如果写得好,执行和序列化最好,但除了一堆其他功能外,你还必须编写并发。
IMO,自ADO.Net 2.0以来,即使在大规模远程处理情况下,数据表也能表现良好。它们提供了特殊的二进制远程处理格式,并且易于使用。抛出一些压缩,你甚至没有为大数据集使用大量带宽。
答案 4 :(得分:0)