2013-07-18 30 views
10

Ok, tôi phải làm điều gì đó câm, nhưng không nên làm việc này? Tôi có ba danh sách sau:Kết hợp ba danh sách thành một với LINQ ném một ngoại lệ

var commonViews = (from v in context.TPM_VIEWS where v.VIEWID < 0 select v); // IQueryable<TPM_VIEWS> 
var ownedViews = (from v in context.TPM_VIEWS where v.OWNERID == userId && v.VIEWID > 0 select v); // IQueryable<TPM_VIEWS> 
var sharedViews = (from v in context.TPM_USER.Include("TPM_VIEWS2") where v.USERID == userId select v).First().TPM_VIEWS2; // EntityCollection<TPM_VIEWS> 

Mỗi danh sách đều có giá trị và số lượng phù hợp. Tôi có thể trả lại bất kỳ một trong những danh sách này:

return commonViews.ToList(); 

Và tôi có thể trở lại một bất kỳ hai của các danh sách này:

return commonViews.Concat(ownedViews).ToList(); 

Tuy nhiên, khi tôi cố gắng trả lại toàn bộ ba:

return commonViews.Concat(ownedViews).Concat(sharedViews).ToList(); 

Tôi nhận ngoại lệ:

Không thể tạo giá trị không đổi của loại 'Entity.TPM_VIEWS'. Chỉ có loại nguyên thủy hoặc kiểu liệt kê mới được hỗ trợ trong ngữ cảnh này.

Tôi đang làm gì sai? Tất cả ba giá trị thực sự là số đếm. Chủ yếu, tôi hỏi câu hỏi này bởi vì đó là cách tốt nhất có thể để đảm bảo tôi sẽ nhận thấy vấn đề 30 giây sau khi đăng.

UPDATE:

Tôi 93% chắc chắn vấn đề là ở đây:

var sharedViews = (from v in context.TPM_USER.Include("TPM_VIEWS2") where v.USERID == userId select v).First().TPM_VIEWS2; 

này trông như một danh sách đếm được của TPM_VIEWS đối tượng, và tôi có thể gọi ToList() vào nó và có được dữ liệu chính xác, nhưng nó không hoạt động tốt với các danh sách khác.

UPDATE 2:

này thực sự hoạt động. Điểm cho người có thể cho tôi biết lý do!

commonViews.ToList().Concat(ownedViews.ToList()).Concat(sharedViews.ToList()).ToList(); 
+0

Thử đặt 'sharedViews' trước. Vâng; Tôi nghiêm túc nghi ngờ rằng sẽ sửa chữa nó. – SLaks

+0

dựa trên lịch sử cực kỳ cơ bản của tôi với EF, tôi sẵn sàng đặt cược một fiver @SLaks là đúng. – JerKimball

+0

Ok yea điều này là lạ. 'sharedViews.Concat (commonViews) .Concat (ownedViews) .Count()' trả về 6 (chính xác), nhưng 'sharedViews.Concat (commonViews) .Concat (ownedViews) .ToList();' ném cùng một ngoại lệ. Đó là một cái gì đó sôi nổi với 'sharedViews' cho chắc chắn. Về cơ bản, tôi cần có một 'IEnumerable ' từ 'userId' đã cho. –

Trả lời

5

Vấn đề là Concat() trên một EF IQueryable<T> sẽ biến toàn bộ nối vào một truy vấn duy nhất.

Khi bạn gọi .Concat(sharedViews), bạn đang chuyển bộ sưu tập vô hướng (được tải sẵn) của lớp tổ chức lồng nhau.
EF không biết cách chuyển đổi thành truy vấn, do đó, nó sẽ phàn nàn.

Bạn có thể làm cho nó nhanh hơn bằng cách gọi AsEnumerable() thay vì ToList().

+0

Tuyệt vời, tôi nghĩ rằng điều này tổng hợp tất cả mọi thứ độc đáo! –

+0

Vì vậy, @MikeChristensen nhận được $ 5 hay không? – Kevin

+0

Tôi chấp nhận PayPal. –

1

Điều này thực sự hiệu quả. Điểm cho người có thể cho tôi biết lý do!

commonViews.ToList().Concat(ownedViews.ToList()).Concat(sharedViews.ToList()).ToList(); 

Đó là vì mỗi truy vấn ban đầu được thực hiện riêng; bạn chỉ ghép nối các kết quả trong bộ nhớ.Dường như có lỗi trong trình dịch truy vấn khung thực thể khi bạn kết hợp 3 truy vấn, nhưng khi bạn gọi ToList trên mỗi truy vấn, chúng không còn là truy vấn EF nữa, chúng chỉ là danh sách, vì vậy chúng được nối bằng cách sử dụng LINQ đối tượng.