นี่อาจเป็นวิธีที่เร็วที่สุดในการสอบถามแถวจำนวนมากด้วย Dapper โดยใช้รายการ ID ฉันสัญญากับคุณว่าจะเร็วกว่าวิธีอื่น ๆ ที่คุณคิด (ยกเว้นการใช้ TVP ตามที่ให้ไว้ในคำตอบอื่นและฉันยังไม่ได้ทดสอบ แต่ฉันสงสัยว่าอาจช้ากว่าเพราะคุณยังต้องใส่ข้อมูล TVP) มันเป็น ดาวเคราะห์ที่เร็วกว่า Dapper โดยใช้IN
ไวยากรณ์และจักรวาลเร็วกว่า Entity Framework ทีละแถว และมันก็ยิ่งเร็วกว่าการผ่านรายการVALUES
หรือUNION ALL SELECT
รายการ สามารถขยายได้อย่างง่ายดายเพื่อใช้คีย์แบบหลายคอลัมน์เพียงเพิ่มคอลัมน์พิเศษลงในDataTable
ตาราง temp และเงื่อนไขการเข้าร่วม
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;
}
}
ระวังว่าคุณต้องเรียนรู้เกี่ยวกับการแทรกจำนวนมากเล็กน้อย มีตัวเลือกเกี่ยวกับทริกเกอร์การยิง (ค่าเริ่มต้นคือไม่มี), เคารพข้อ จำกัด , ล็อคตาราง, อนุญาตการแทรกพร้อมกัน, และอื่น ๆ