IDのリストを使用して、Dapperで多数の行をクエリする最も高速な方法は次のとおりです。これはあなたが考えることができる他のほとんどすべての方法よりも速いことを約束します(別の回答で示されたTVPの使用の可能性のある例外はありますが、私はテストしていませんが、まだ入力する必要があるので遅いかもしれません)TVP)。これは、ある 惑星速くDapperのは、使用するよりもIN
構文とユニバースをより速く行により、Entity Frameworkの行よりも。また、リストのVALUES
やUNION ALL SELECT
アイテムを渡すよりも大陸の方が高速です。複数列のキーを使用するように簡単に拡張できます。追加の列をDataTable
、一時テーブル、および結合条件に追加するだけです。
public IReadOnlyCollection<Item> GetItemsByItemIds(IEnumerable<int> items) {
var itemList = new HashSet(items);
if (itemList.Count == 0) { return Enumerable.Empty<Item>().ToList().AsReadOnly(); }
var itemDataTable = new DataTable();
itemDataTable.Columns.Add("ItemId", typeof(int));
itemList.ForEach(itemid => itemDataTable.Rows.Add(itemid));
using (SqlConnection conn = GetConnection()) // however you get a connection
using (var transaction = conn.BeginTransaction()) {
conn.Execute(
"CREATE TABLE #Items (ItemId int NOT NULL PRIMARY KEY CLUSTERED);",
transaction: transaction
);
new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, transaction) {
DestinationTableName = "#Items",
BulkCopyTimeout = 3600 // ridiculously large
}
.WriteToServer(itemDataTable);
var result = conn
.Query<Item>(@"
SELECT i.ItemId, i.ItemName
FROM #Items x INNER JOIN dbo.Items i ON x.ItemId = i.ItemId
DROP TABLE #Items;",
transaction: transaction,
commandTimeout: 3600
)
.ToList()
.AsReadOnly();
transaction.Rollback(); // Or commit if you like
return result;
}
}
一括挿入について少し学ぶ必要があることに注意してください。トリガーの起動(デフォルトはno)、制約の尊重、テーブルのロック、同時挿入の許可などに関するオプションがあります。