关于Linq中的左连接已经有很多关于SO的问题,而我所看到的都使用join
关键字来实现所需的结束。
这对我没有意义。假设我有Customer
和Invoice
表,由CustomerID
上的外键Invoice
链接。现在我想运行一份包含客户信息以及任何发票的报告。 SQL将是:
select c.*, i.*
from Customer c
left join Invoice i on c.ID = i.CustomerID
从我所看到的关于SO的答案,人们大多建议:
var q = from c in Customers
join i in Invoices.DefaultIfEmpty() on c.ID equals i.CustomerID
select new { c, i };
我真的不明白这是怎样唯一的方法。 Customer
和Invoice
之间的关系已由LinqToSQL类定义;我为什么要为join
条款重复它?如果我想要一个内部联接,它只会是:
var q = from c in Customers
from i in c.Invoices
select new { c, i };
未指定连接字段!
我试过了:
var q = from c in Customers
from i in c.Invoices.DefaultIfEmpty()
select new { c, i };
但这只是给了我相同的结果,就好像它是一个内连接。
有没有更好的方法呢?
答案 0 :(得分:6)
虽然已经定义了关系(在数据库和.dbml标记中),但运行时无法自动确定它是否应该使用该关系。
如果对象模型中有两个关系(Person有父母和子女,两者都与其他Person实例有关系),该怎么办?虽然案件可能是特殊情况,但这会使系统更复杂(因此更多的错误)。请记住,在SQL中,您将重复关系的规范。
记住索引和键是一个实现细节,而不是作为关系模型基础的关系代数的一部分。
如果你想要LEFT OUTER JOIN,那么你需要使用“into
”:
from c in Customers
join i in Invoices on i.CustomerId equals c.CustomerId into inv
...
和inv将具有类型IEnumerable<Invoivce>
,可能没有实例。
答案 1 :(得分:5)
from i in c.Invoice.DefaultIfEmpty()
恰好是左连接。
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);
}
此测试产生:
ValueOfStringIs|Foo| ValueOfCharIs|70|
ValueOfStringIs|Foo| ValueOfCharIs|111|
ValueOfStringIs|Foo| ValueOfCharIs|111|
ValueOfStringIs|| ValueOfCharIs|0|
答案 2 :(得分:2)
您可能想要使用'into'关键字。