Vấn đề giới hạn tham số 2100 không tồn tại trong EF.
Tôi đã chạy thử nghiệm trên the AdventureWorks database (trong SQL Express 2008 R2): Tôi đang cố gắng lấy tất cả các sản phẩm trong đó ProductCategoryId
nằm trong phạm vi giá trị (1, 2, 3).
Sử dụng LINQ, được tạo ra SQL WHERE
khoản trông như thế này:
WHERE [t0].[ProductCategoryID] IN (@p0, @p1, @p2)
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1]
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [2]
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [3]
(dẫn đến các vấn đề số tham số tối đa), trong khi với EF 4,0 nó trông như thế này:
WHERE [Extent1].[ProductCategoryID] IN (1,2,3)
Tiếp theo, tôi đã thử nghiệm điều này với EF để có danh sách 3000 giá trị:
var categoryList = Enumerable.Range(1, 3000).Select(i => (int?)i).ToArray();
using (var aw = new AdventureWorksEntities())
{
var products = aw.Products
.Where(p => categoryList.Contains(p.ProductCategoryID))
.ToList();
}
Trong khi điều này cực kỳ kém hiệu quả, nó hoạt động và mang lại kết quả mong đợi.
Tuy nhiên, nó cũng có thể sử dụng InRange
mở rộng provided by Marc Gravell với EF, bởi cũng sử dụng LINQKit library, như vậy:
using (var aw = new AdventureWorksEntities())
{
var products = aw.Products
.AsExpandable()
.InRange(p => p.ProductCategoryID, 1000, categoryList)
.ToList();
}
(phần mở rộng AsExpandable
được định nghĩa trong LINQKit)
này tạo ra kết quả mong đợi (thực hiện truy vấn theo khối) và, tùy thuộc vào số lượng các mục trong danh sách và kích thước của đoạn có thể hiệu quả hơn nhiều so với giải pháp không chunked.
Tạo truy vấn yêu cầu hơn 2100 mục được xác định tĩnh cho câu lệnh 'IN' (phần truy cập của' Contains') trông không giống một cách tiếp cận đúng. Hoạt động như vậy nên được xử lý hoàn toàn trên DB mà không cần truyền dữ liệu từ máy khách. –
Tôi hiểu mối quan tâm của bạn, nhưng chắc chắn có trường hợp trong đó * tất cả * dữ liệu bắt buộc sẽ không có trong cơ sở dữ liệu. Có những lựa chọn thay thế để truyền một danh sách lớn các tham số, nhưng điều bắt mắt đơn giản này là cực kỳ linh hoạt cho cách chúng ta muốn sử dụng nó (và 99% thời gian nó không cần sử dụng nó). – Ocelot20