首页 文章

左连接Linq查询

提问于
浏览
5

我正在尝试进行左连接,而不是linq查询中的内连接 . 我找到了与使用_1772085相关的答案,但我似乎无法使其工作 . 以下是linq查询:

from a in dc.Table1 
join e in dc.Table2 on a.Table1_id equals e.Table2_id
where a.Table1_id == id
orderby a.sort descending
group e by new
{
    a.Field1,
    a.Field2
} into ga
select new MyObject
{
    field1= ga.Key.Field1,
    field2= ga.Key.Field2,
    manySubObjects = (from g in ga select new SubObject{
                                                        fielda= g.fielda,
                                                        fieldb= g.fieldb
                                                        }).ToList()
}).ToList();

该查询仅向我提供表1中具有表2中相应记录的行 . 我希望表1中的每条记录都填充到MyObject中,并且每个MyObject的manySubObjects中列出的0-n对应记录列表 .

更新:我尝试了下面提到的“可能重复”的问题的答案 . 我现在有以下代码,即使没有Table2记录,也会为Table1中的每个项目提供一条记录 .

from a in dc.Table1 
join e in dc.Table2 on a.Table1_id equals e.Table2_id into j1
from j2 in j1.DefaultIfEmpty()
where a.Table1_id == id
orderby a.sort descending
group j2 by new
{
    a.Field1,
    a.Field2
} into ga
select new MyObject
{
    field1= ga.Key.Field1,
    field2= ga.Key.Field2,
    manySubObjects = (from g in ga select new SubObject{
                                                        fielda= g.fielda,
                                                        fieldb= g.fieldb
                                                        }).ToList()
}).ToList();

但是,使用此代码,当table2中没有记录时,我将“manySubObject”作为一个列表,其中包含一个“SubObject”,其中包含“SubObject”属性的所有空值 . 如果table2中没有值,我真正想要的是“manySubObjects”为null .

3 回答

  • 3

    In reply to your update ,要创建空列表,您可以在 manySubObjects 的任务中执行三元组 .

    select new MyObject
    {
        field1= ga.Key.Field1,
        field2= ga.Key.Field2,
        manySubObjects =
            (from g in ga select g).FirstOrDefaut() == null ? null : 
            (from g in ga select new SubObject {
               fielda= g.fielda,
               fieldb= g.fieldb
            }).ToList()
    }).ToList();
    

    In reply to your comments ,上面的内容适用于Linq to Objects,但不适用于Linq to SQL . Linq to SQL会抱怨它,"Could not translate expression ... into SQL and could not treat as a local expression."那是因为Linq无法将自定义 new SubObject 构造函数转换为SQL . 为此,您必须编写更多代码以支持转换为SQL . 见Custom Method in LINQ to SQL querythis article .

    我想我们已经充分回答了你关于左连接的原始问题 . 考虑在Linq to SQL查询中询问有关使用自定义方法/构造函数的新问题 .

  • 3

    我认为你想要的结果可以通过GroupJoin()给出

    下面的代码将生成一个类似的结构

    Field1,Field2,List <SubObject> null如果为空

    示例代码

    var query = dc.Table1.Where(x => Table1_id == id).OrderBy(x => x.sort)
                    .GroupJoin(dc.Table2, (table1 => table1.Table1_id), (table2 => table2.Table2_id),
                        (table1, table2) => new MyObject 
                                            { 
                                                field1 = table1.Field1, 
                                                field2 = table1.Field2, 
                                                manySubObjects = (table2.Count() > 0) 
                                                    ? (from t in table2 select new SubObject { fielda = t.fielda, fieldb = t.fieldb}).ToList()
                                                    : null 
                                            }).ToList();
    

    Dotnetfiddle link

    UPDATE

    从你的评论我看到了这一点

    ga.Select(g = > new SubObject(){fielda = g.fielda, fieldb = g.fieldb})
    

    我认为应该是(取决于如何 Build “ga”)

    ga.Select(g => new SubObject {fielda = g.fielda, fieldb = g.fieldb})
    

    请使用整个查询更新您的问题,这将有助于解决问题 .

    **更新BIS **

    sentEmails = //ga.Count() < 1 ? null :
                  //(from g in ga select g).FirstOrDefault() == null ? null :
                 (from g in ga select new Email{
                      email_to = g.email_to,
                      email_from = g.email_from,
                      email_cc = g.email_cc,
                      email_bcc = g.email_bcc,
                      email_subject = g.email_subject,
                      email_body = g.email_body }).ToList()
    

    应该:

    sentEmails = //ga.Count() < 1 ? null :
                 ((from g in ga select g).FirstOrDefault() == null) ? null :
                 (from g in ga select new Email{
                      email_to = g.email_to,
                      email_from = g.email_from,
                      email_cc = g.email_cc,
                      email_bcc = g.email_bcc,
                      email_subject = g.email_subject,
                      email_body = g.email_body }).ToList()
    

    检查该组是否具有First,如果该组没有任何记录,则Time Stamp的Action.Name没有要发送的电子邮件 . 如果First不为null,则循环抛出组元素并创建Email列表,

  • 0
    var results =
    (
        // Use from, from like so for the left join:
        from a in dc.Table1
        from e in dc.Table2
            // Join condition goes here
            .Where(a.Id == e.Id)
            // This is for the left join
            .DefaultIfEmpty()
        // Non-join conditions here
        where a.Id == id
        // Then group
        group by new
        {
            a.Field1,
            a.Field2
        }
    ).Select(g =>
        // Sort items within groups
        g.OrderBy(item => item.sortField)
        // Project required data only from each item
        .Select(item => new
        {
            item.FieldA,
            item.FieldB
        }))
    // Bring into memory
    .ToList();
    

    然后在内存中投影到非EF模型类型 .

相关问题