这可能是使用 Dapper 使用 ID 列表查询大量行的最快方法。我向你保证,这比你能想到的几乎任何其他方式都快(除了使用另一个答案中给出的 TVP 并且我没有测试过,但我怀疑可能会慢一些,因为你仍然需要填充电视节目)。它 使用语法比 Dapper 快行星,逐行比 Entity Framework 快。它甚至比传递一个或多个项目的列表还要快。它可以很容易地扩展为使用多列键,只需将额外的列添加到临时表和连接条件中。IN
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)、尊重约束、锁定表、允许并发插入等选项。