这与特定问题无关但是关于“最佳实践”的问题。
有一段时间了,当我需要从数据库直接获取数据时,我一直在使用以下方法 - 我想知道是否有一种我不知道的更快的方法?
DataTable results = new DataTable();
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Name"]))
{
connection.Open();
using (SqlCommand command = new SqlCommand("StoredProcedureName",connection))
{
command.CommandType = CommandType.StoredProcedure;
/*Optionally set command.Parameters here*/
results.Load(command.ExecuteReader());
}
}
/*Do something useful with the results*/
答案 0 :(得分:4)
确实有各种方法来读取数据; DataTable
是一个非常复杂的野兽(支持许多复杂的场景 - 参照完整性,约束,计算值,动态额外列,索引,过滤等)。在很多情况下,你不需要所有;你只想要数据。为此,在内存和性能方面,简单的对象模型可以更有效。您可以围绕IDataReader
编写自己的代码,但这是一个已解决的问题,有一系列工具可以帮助您。例如,您可以通过dapper完成此操作,只需:
class SomeTypeOfRow { // define something that looks like the results
public int Id {get;set;}
public string Name {get;set;}
//..
}
...
var rows = connection.Query<SomeTypeOfRow>("StoredProcedureName",
/* optionalParameters, */ commandType: CommandType.StoredProcedure).ToList();
然后非常有效地填充List<SomeTypeOfRow>
,而没有所有DataTable
开销。此外,如果您要处理大量数据,则可以执行此操作
这是一个完全流式的方式,所以你不需要在内存中缓冲2M行:
var rows = connection.Query<SomeTypeOfRow>("StoredProcedureName",
/* optionalParameters, */ commandType: CommandType.StoredProcedure,
buffered: false); // an IEnumerable<SomeTypeOfRow>
为了完整起见,我应该解释optionalParameters
;如果你想传递@id=1
,@name="abc"
,那就是:
var rows = connection.Query<SomeTypeOfRow>("StoredProcedureName",
new { id = 1, name = "abc" },
commandType: CommandType.StoredProcedure).ToList();
,我认为你会同意,这是一种描述参数的简洁方法。此参数完全是可选的,如果不需要参数,则可以省略。
作为一个额外的奖励,它意味着你可以免费获得强类型,即
foreach(var row in rows) {
Console.WriteLine(row.Id);
Console.WriteLine(row.Name);
}
而不是谈论row["Id"]
,row["Name"]
等。