2009-07-07 37 views
5

Có rất nhiều câu hỏi về SO đã được về tham gia trái trong LINQ, và những cái tôi đã nhìn tất cả sử dụng các từ khóa join để đạt được kết thúc mong muốn.Tham gia lại trong LINQ?

Điều này không có ý nghĩa với tôi. Giả sử tôi có các bảng CustomerInvoice, được liên kết bằng khóa ngoài CustomerID trên Invoice. Bây giờ tôi muốn chạy báo cáo chứa thông tin khách hàng, cộng với mọi hóa đơn. SQL sẽ là:

select c.*, i.* 
    from Customer c 
    left join Invoice i on c.ID = i.CustomerID 

Từ những gì tôi đã nhìn thấy các câu trả lời trên SO, người ta chủ yếu là gợi ý:

var q = from c in Customers 
     join i in Invoices.DefaultIfEmpty() on c.ID equals i.CustomerID 
     select new { c, i }; 

Tôi thật sự không hiểu làm thế nào điều này có thể là cách duy nhất. Mối quan hệ giữa CustomerInvoice đã được xác định bởi các lớp LinqToSQL; tại sao tôi phải lặp lại nó cho mệnh đề join? Nếu tôi muốn tham gia bên trong, nó sẽ đơn giản là:

var q = from c in Customers 
     from i in c.Invoices 
     select new { c, i }; 

mà không chỉ định trường đã tham gia!

tôi đã cố gắng:

var q = from c in Customers 
     from i in c.Invoices.DefaultIfEmpty() 
     select new { c, i }; 

nhưng điều đó chỉ cho tôi cùng một kết quả như thể nó là một bên tham gia.

Không có cách nào tốt hơn để làm điều này?

Trả lời

5

Bạn đang nói về điều gì? Điều đó from i in c.Invoice.DefaultIfEmpty() chính xác là một tham gia trái.

 List<string> strings = new List<string>() { "Foo", "" }; 

     var q = from s in strings 
       from c in s.DefaultIfEmpty() 
       select new { s, c }; 

     foreach (var x in q) 
     { 
      Console.WriteLine("ValueOfStringIs|{0}| ValueOfCharIs|{1}|", 
       x.s, 
       (int)x.c); 
     } 

thử nghiệm này tạo ra:

ValueOfStringIs|Foo| ValueOfCharIs|70| 
ValueOfStringIs|Foo| ValueOfCharIs|111| 
ValueOfStringIs|Foo| ValueOfCharIs|111| 
ValueOfStringIs|| ValueOfCharIs|0| 
+1

Cũng thổi tôi xuống - bạn đã đúng! Bây giờ, tại sao tôi nghĩ rằng điều này đã không làm việc ...? OK, tôi khiêm tốn trở lại ... câu hỏi này là do sự hiểu lầm của riêng tôi. CẢM ƠN! :) –

2

Có thể bạn muốn sử dụng từ khóa 'vào'.

Example

+0

Cảm ơn, nhưng điều này không thực sự trả lời câu hỏi của tôi ... là có không phải là một cách tốt hơn, lợi dụng thực tế là mối quan hệ đã được xác định? –

6

Trong khi mối quan hệ đã được xác định (cả về cơ sở dữ liệu và trong đánh dấu dbml) thời gian chạy không thể tự động xác định xem nó nên sử dụng mối quan hệ đó.

Điều gì xảy ra nếu có hai mối quan hệ trong mô hình đối tượng (Người có Cha mẹ và Trẻ em, cả hai mối quan hệ với các cá thể Người khác). Trong khi các trường hợp có thể được đặc biệt cased, điều này sẽ làm cho hệ thống phức tạp hơn (do đó, nhiều lỗi). Hãy nhớ trong SQL bạn sẽ lặp lại đặc tả của mối quan hệ.

Ghi chỉ mục và khóa là chi tiết triển khai và không phải là một phần của đại số quan hệ làm nền tảng cho mô hình quan hệ.

Nếu bạn muốn có một LEFT OUTER JOIN thì bạn cần phải sử dụng "into":

from c in Customers 
join i in Invoices on i.CustomerId equals c.CustomerId into inv 
... 

và inv sẽ có loại IEnumerable<Invoivce>, có thể không có trường hợp.

+0

+1 Câu trả lời hay, nhưng bạn vẫn còn thiếu quan điểm của tôi.Hóa đơn cụ thể có mối quan hệ "Khách hàng" được xác định và tôi muốn sử dụng mối quan hệ THAT: "c.Invoices", không chỉ là "Hóa đơn". Có cách nào để làm điều đó? –

+0

@Shaul: Sau đó, làm như vậy, chỉ cần sử dụng c.Invoices trong biểu thức. Nếu bạn muốn có một định danh khác thì sử dụng mệnh đề let. – Richard

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