离开加入Linq?

Sha*_*ica 5 c# linq linq-to-sql

关于Linq中的Left连接已经有很多关于SO的问题,而我所看到的都使用join关键字来实现期望的结束.

这对我来说没有意义.比方说,我有表CustomerInvoice由外键链接CustomerIDInvoice.现在我想运行一份包含客户信息以及任何发票的报告.SQL将是:

select c.*, i.*
  from Customer c
  left join Invoice i on c.ID = i.CustomerID
Run Code Online (Sandbox Code Playgroud)

从我所看到的关于SO的答案,人们大多建议:

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

我真的不明白这是怎么回事.Customer和之间的关系Invoice已经由LinqToSQL类定义; 我为什么要为join条款重复一遍呢?如果我想要一个内部联接,它只会是:

var q = from c in Customers
        from i in c.Invoices
        select new { c, i };
Run Code Online (Sandbox Code Playgroud)

没有指定连接的字段!

我试过了:

var q = from c in Customers
        from i in c.Invoices.DefaultIfEmpty()
        select new { c, i };
Run Code Online (Sandbox Code Playgroud)

但这只是给了我相同的结果,就好像它是一个内部联接.

有没有更好的方法来做到这一点?

Ric*_*ard 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
...
Run Code Online (Sandbox Code Playgroud)

和inv将有类型IEnumerable<Invoivce>,可能没有实例.


Amy*_*y B 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);
        }
Run Code Online (Sandbox Code Playgroud)

该测试产生:

ValueOfStringIs|Foo| ValueOfCharIs|70|
ValueOfStringIs|Foo| ValueOfCharIs|111|
ValueOfStringIs|Foo| ValueOfCharIs|111|
ValueOfStringIs|| ValueOfCharIs|0|
Run Code Online (Sandbox Code Playgroud)