2011-10-05 33 views
61

Tôi đang cố triển khai truy vấn trong LINQ sử dụng phép nối ngoài bên trái với nhiều điều kiện trong mệnh đề ON.LINQ Tham gia với nhiều điều kiện trong điều khoản

tôi sẽ sử dụng các ví dụ về hai bảng sau Dự án (ProjectID, ProjectName) và công tác (taskID, ProjectID, taskname, hoàn thành). Tôi muốn xem danh sách đầy đủ của tất cả các dự án với nhiệm vụ tương ứng của họ, nhưng chỉ những nhiệm vụ được hoàn thành.

Tôi không thể sử dụng bộ lọc cho Completed == true vì điều đó sẽ lọc ra bất kỳ dự án nào không có tác vụ hoàn thành. Thay vào đó, tôi muốn thêm Completed == true vào mệnh đề ON của phép nối để danh sách đầy đủ các dự án sẽ được hiển thị, nhưng chỉ các tác vụ đã hoàn thành mới được hiển thị. Các dự án không có nhiệm vụ hoàn thành sẽ hiển thị một hàng duy nhất có giá trị null cho Tác vụ.

Đây là nền tảng của truy vấn.

from t1 in Projects 
join t2 in Tasks 
on new { t1.ProjectID} equals new { t2.ProjectID } into j1 
from j2 in j1.DefaultIfEmpty() 
select new { t1.ProjectName, t2.TaskName } 

Làm cách nào để thêm && t2.Completed == true vào mệnh đề trên?

Tôi dường như không tìm thấy bất kỳ tài liệu LINQ nào về cách thực hiện việc này.

Trả lời

82

Bạn chỉ cần đặt tên cho tài sản mang tính chất giống nhau trên cả hai bên

on new { t1.ProjectID, SecondProperty = true } equals 
    new { t2.ProjectID, SecondProperty = t2.Completed } into j1 

Dựa trên ý kiến ​​của @svick, đây là một thực hiện mà có thể làm cho ý nghĩa hơn:

from t1 in Projects 
from t2 in Tasks.Where(x => t1.ProjectID == x.ProjectID && x.Completed == true) 
       .DefaultIfEmpty() 
select new { t1.ProjectName, t2.TaskName } 
+0

Đó có vẻ như một cách không rõ ràng để làm điều đó. Tôi không chắc tôi sẽ hiểu những gì nó giả định để làm. – svick

+1

@svick - Sử dụng các loại ẩn danh cho phép bạn tham gia vào nhiều tiêu chí. Bạn chỉ cần đảm bảo tên thuộc tính khớp với cả hai loại. Bạn không chắc chắn sự nhầm lẫn đến từ đâu? – Aducci

+0

Sự nhầm lẫn là nó thực sự có ý nghĩa hơn khi hai sự cân bằng tham gia bởi 'và', không phải là một bình đẳng của một số đối tượng" lạ ". Và để chứng minh quan điểm của tôi, mã của bạn là sai. Đối với nó làm việc, bạn sẽ phải có 'true' ở phía bên trái và' t2.Complete' ở bên phải. – svick

2

Bạn không thể làm như vậy. Điều khoản join (và phương pháp mở rộng Join()) chỉ hỗ trợ equijoins. Đó cũng là lý do, tại sao nó sử dụng equals và không phải ==. Và ngay cả khi bạn có thể làm một cái gì đó như thế, nó sẽ không hoạt động, bởi vì join là một tham gia bên trong, không phải bên ngoài tham gia.

20

Ở đây bạn đi với:

from b in _dbContext.Burden 
join bl in _dbContext.BurdenLookups on 
new { Organization_Type = b.Organization_Type_ID, Cost_Type = b.Cost_Type_ID } equals 
new { Organization_Type = bl.Organization_Type_ID, Cost_Type = bl.Cost_Type_ID } 
Các vấn đề liên quan