3

这与特定问题无关,而是关于“最佳实践”的问题。

一段时间以来,当我需要直接从数据库中获取数据时,我一直在使用以下方法 - 我想知道是否有一种我不知道的更快的方法?

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*/
4

1 回答 1

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();

然后非常有效地填充 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"]

于 2012-10-11T12:52:25.947 回答