Muhtemelen bir kimlik listesi kullanarak Dapper ile çok sayıda satırı sorgulamanın en hızlı yolu. Size bunun aklınıza gelebilecek diğer tüm yöntemlerden daha hızlı olduğuna söz veriyorum (başka bir cevapta verildiği gibi bir TVP'yi kullanmak dışında ve test etmediğimden şüpheleniyorum, ancak daha yavaş olabileceğinden şüpheleniyorum çünkü hala doldurmanız gerekiyor TVP). Öyle gezegenler daha hızlı Zarif kullanmaktan daha IN
sözdizimi ve evreni daha hızlı sıranın tarafından varlık Framework sıradan daha. Ve kıtalar bile bir liste VALUES
veya UNION ALL SELECT
öğelerden daha hızlıdır . Çok sütunlu bir anahtar kullanmak için kolayca genişletilebilir, sadece DataTable
geçici tabloya, geçici tabloya ve birleştirme koşullarına ekleyin .
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;
}
}
Toplu Eklemeler hakkında biraz bilgi sahibi olmanız gerektiğini unutmayın. Ateşleme tetikleyicileri (varsayılan değer hayır), kısıtlamalara uyma, tabloyu kilitleme, eşzamanlı eklemelere izin verme vb. Seçenekleri vardır.