确实有多种读取数据的方法;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();
然后非常有效地填充 a 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"]
。