【问题标题】:Left join in Linq?离开加入 Linq?
【发布时间】:2009-07-08 03:20:26
【问题描述】:

关于 SO 已经有很多关于 Linq 中的左连接的问题,而我看过的所有问题都使用 join 关键字来达到预期的目的。

这对我来说没有意义。假设我有表CustomerInvoice,通过Invoice 上的外键CustomerID 链接。现在我想运行一个包含客户信息以及任何发票的报告。 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 };

我真的不明白这怎么可能是唯一的方法。 CustomerInvoice 之间的关系已经由 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 };

但这只是给了我与内部连接相同的结果。

没有更好的方法吗?

【问题讨论】:

    标签: c# linq linq-to-sql


    【解决方案1】:

    虽然已经定义了关系(在数据库和 .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 很好的答案,但你仍然错过了我的观点。发票明确定义了“客户”关系,我想利用这种关系:“c.Invoices”,而不仅仅是“Invoices”。有什么办法吗?
    • @Shaul:然后这样做,只需在表达式中使用 c.Invoices 即可。如果您想要不同的标识符,请使用 let 子句。
    【解决方案2】:

    你在说什么? 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|
    

    【讨论】:

    • 好吧,让我失望 - 你是对的!现在,为什么我认为这不起作用......?好吧,我谦虚地退缩了……这个问题是我自己的误解造成的。谢谢! :)
    【解决方案3】:

    您可能想要使用“into”关键字。

    Example

    【讨论】:

    • 谢谢,但这并不能真正回答我的问题......难道没有更好的方法,利用关系已经定义的事实吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    相关资源
    最近更新 更多