2012-01-17 28 views
6

Tôi đang di chuyển một số mã của chúng tôi từ LINQ-to-SQL sang khung thực thể. Trước đây, khi chạy lên chống lại giới hạn thông số 2100 từ SQL Server (được mô tả here), tôi đã sử dụng giải pháp được cung cấp bởi Marc Gravell here. Như đã nêu trong phản hồi của chính mình, nó không hoạt động với Entity Framework.Khuôn khổ thực thể Nhấn 2100 Tham số giới hạn

Tôi hoàn toàn thiếu kinh nghiệm với các biểu thức để biết bắt đầu từ đâu, nhưng những gì tôi đang tìm về cơ bản là cùng một phương pháp mở rộng nhưng có thể áp dụng cho Khung thực thể. Cảm ơn trước vì bất kỳ trợ giúp nào bạn có thể cung cấp.

+1

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. –

+0

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

Trả lời

13

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.

Các vấn đề liên quan