C# 离开加入Linq?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1092562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Left join in Linq?
提问by Shaul Behr
There are a lot of questions on SO already about Left joins in Linq, and the ones I've looked at all use the join
keyword to achieve the desired end.
关于Linq中的Left joins已经有很多问题了,我看过的所有问题都使用join
关键字来达到预期的目的。
This does not make sense to me. Let's say I have the tables Customer
and Invoice
, linked by a foreign key CustomerID
on Invoice
. Now I want to run a report containing customer info, plus any invoices. SQL would be:
这对我来说没有意义。比方说,我有表Customer
和Invoice
由外键链接CustomerID
上Invoice
。现在我想运行一个包含客户信息以及任何发票的报告。SQL 将是:
select c.*, i.*
from Customer c
left join Invoice i on c.ID = i.CustomerID
From what I've seen of the answers on SO, people are mostly suggesting:
从我所看到的关于 SO 的答案来看,人们大多建议:
var q = from c in Customers
join i in Invoices.DefaultIfEmpty() on c.ID equals i.CustomerID
select new { c, i };
I really don't understand how this can be the only way. The relationship between Customer
and Invoice
is already defined by the LinqToSQL classes; why should I have to repeat it for the join
clause? If I wanted an inner join it would simply have been:
我真的不明白这怎么可能是唯一的方法。Customer
和之间的关系Invoice
已经由 LinqToSQL 类定义;为什么我必须为该join
条款重复它?如果我想要一个内部连接,它只会是:
var q = from c in Customers
from i in c.Invoices
select new { c, i };
without specifying the joined fields!
不指定连接的字段!
I tried:
我试过:
var q = from c in Customers
from i in c.Invoices.DefaultIfEmpty()
select new { c, i };
but that just gave me the same result as if it were an inner join.
但这只是给了我与内部连接相同的结果。
Is there not a better way of doing this?
没有更好的方法来做到这一点吗?
采纳答案by Amy B
What are you talking about? That from i in c.Invoice.DefaultIfEmpty()
is exactly a left join.
你在说什么?这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);
}
This test produces:
该测试产生:
ValueOfStringIs|Foo| ValueOfCharIs|70|
ValueOfStringIs|Foo| ValueOfCharIs|111|
ValueOfStringIs|Foo| ValueOfCharIs|111|
ValueOfStringIs|| ValueOfCharIs|0|
回答by Richard
While the relationship is already defined (both in the database and in the .dbml markup) the runtime cannot automatically determine if it should use that relationship.
虽然已经定义了关系(在数据库和 .dbml 标记中),但运行时无法自动确定是否应该使用该关系。
What if there are two relationships in the object model (Person has Parents and Children, both relationships to other Person instances). While cases could be special cased, this would make the system more complex (so more bugs). Remember in SQL you would repeat the specification of the relationship.
如果对象模型中有两个关系(Person 有Parents 和Children,都与其他Person 实例的关系)怎么办。虽然情况可能是特殊情况,但这会使系统更复杂(因此会出现更多错误)。请记住,在 SQL 中您将重复关系的规范。
Remember indexes and keys are an implementation detail and not part of the relational algebra that underlies the relation model.
请记住,索引和键是一个实现细节,而不是关系模型基础的关系代数的一部分。
If you want a LEFT OUTER JOIN then you need to use "into
":
如果你想要一个 LEFT OUTER JOIN 那么你需要使用“ into
”:
from c in Customers
join i in Invoices on i.CustomerId equals c.CustomerId into inv
...
and inv will have type IEnumerable<Invoivce>
, possibly with no instances.
并且 inv 将具有 type IEnumerable<Invoivce>
,可能没有实例。