Berikut ini mungkin cara tercepat untuk meminta sejumlah besar baris dengan Dapper menggunakan daftar ID. Saya berjanji kepada Anda ini lebih cepat daripada hampir semua cara lain yang dapat Anda pikirkan (dengan kemungkinan pengecualian menggunakan TVP seperti yang diberikan dalam jawaban lain, dan yang belum saya uji, tapi saya curiga mungkin lebih lambat karena Anda masih harus mengisi TVP). Ini adalah planet yang lebih cepat dari Dapper menggunakan IN
sintaks dan semesta lebih cepat dari Entity Framework baris demi baris. Dan itu bahkan benua lebih cepat daripada melewati daftar VALUES
atau UNION ALL SELECT
item. Dapat dengan mudah diperluas untuk menggunakan kunci multi-kolom, cukup tambahkan kolom ekstra ke DataTable
, tabel temp, dan kondisi gabungan.
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;
}
}
Perlu diketahui bahwa Anda perlu belajar sedikit tentang Sisipan Massal. Ada beberapa opsi tentang pemicu pemicu (defaultnya adalah tidak), menghormati batasan, mengunci tabel, memungkinkan penyisipan bersamaan, dan sebagainya.