다음은 ID 목록을 사용하여 Dapper로 많은 수의 행을 쿼리하는 가장 빠른 방법입니다. 나는 이것이 당신이 생각할 수있는 거의 모든 다른 방법보다 빠르다고 약속합니다 (다른 답변에서 주어진 TVP를 사용하는 것을 제외하고는 테스트하지 않았지만 여전히 채워야 하기 때문에 속도가 느릴 수 있습니다) TVP). 그것은이다 행성 빠르고 말끔이 사용하는 것보다 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;
}
}
벌크 인서트에 대해 약간 배워야합니다. 트리거 발생 (기본값은 아니오), 제한 조건 존중, 테이블 잠금, 동시 삽입 허용 등에 대한 옵션이 있습니다.