是否有更好/更快的方式来访问原始数据?

时间:2012-10-11 12:33:05

标签: c# asp.net

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

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

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

1 个答案:

答案 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"]等。