C# Linq 中 lambda/方法语法中的左外连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12075905/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 20:16:53  来源:igfitidea点击:

left outer join in lambda/method syntax in Linq

c#.netlinq

提问by NomenNescio

Possible Duplicate:
How do you perform a left outer join using linq extension methods

可能的重复:
如何使用 linq 扩展方法执行左外连接

I can't find a left outer join example of Linq lambda (with extension methods), at least, not a clear one.

我找不到 Linq lambda 的左外连接示例(带有扩展方法),至少,不是一个清晰的示例。

Let's say I have the following table:

假设我有下表:

Parent
{
    PID     // PK
}

Child
{
    CID     // PK
    PID     // FK
    Text
}

I want to join Parent with Child, and for every child missing, I want the default value for Text to be "[[Empty]]". How can I do this with linq lambda syntax?

我想将 Parent 与 Child 一起加入,对于每个丢失的孩子,我希望 Text 的默认值为“[[Empty]]”。我怎样才能用 linq lambda 语法做到这一点?

I currently have the following:

我目前有以下几点:

var source = lParent.GroupJoin(
    lChild,
    p => p.PID,
    c => c.PID,
    (p, g) =>
        new // ParentChildJoined
        {
            PID = p.PID;
            // How do I add child values here?
        });

采纳答案by Rawling

You're close. The following will select PID, CIDand Textfor each child, and PID, CID = -1and Text = "[[Empty]]"for each parent with no children:

你很接近。以下将为每个孩子选择PID,CID和,以及为每个没有孩子的父母选择:TextPIDCID = -1Text = "[[Empty]]"

var source = lParent.GroupJoin(
    lChild,
    p => p.PID,
    c => c.PID,
    (p, g) => g
        .Select(c => new { PID = p.PID, CID = c.CID, Text = c.Text })
        .DefaultIfEmpty(new { PID = p.PID, CID = -1, Text = "[[Empty]]" }))
    .SelectMany(g => g);

回答by Amiram Korach

from p in Parent
join c in Child on p.PID equals c.PID into g
from c in g.DefaultIfEmpty()
select new 
{
   p.PID,
   CID = c != null ? (int?)c.CID : null, // Could be null
   Text = c != null ? c.Text : "[[Empty]]"
}

With lambda:

使用 lambda:

class ChildResult
{
   public int PID { get; set; }
   public int? CID { get; set; }
   public string Text { get; set; }
}

lParent.SelectMany(p => p.Childs.Any() ?
  p.Childs.Select(c => new ChildResult() { PID = c.PID, CID = c.CID, Text = c.Text }) :
  new [] { new ChildResult() { PID = p.PID, CID = null, Text = "[[Empty]]" } } );