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

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 に答える