left join in Linq query
我正在尝试执行左联接,而不是LINQ查询中的内部联接。我已经找到了与使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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对应记录的列表。
更新:我试着回答下面提到的"可能重复"的问题。现在我有了下面的代码,它为表1中的每个项目提供了一条记录,即使没有表2记录。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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(); |
但是,使用此代码,当表2中没有记录时,我将"manysubobject"作为一个列表,其中有一个"subobject",其中包含"subobject"属性的所有空值。我真正想要的是,如果表2中没有值,"manysubobjects"为空。
我想你想要的结果可以用groupjoin()给出。
下面的代码将生成这样的结构
field1,field2,list
样例代码
1 2 3 4 5 6 7 8 9 10 | 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(); |
dotnefiddle链接
更新
从你的评论我看到了这个
1 |
我认为应该是(取决于"GA"是如何构建的)
1 |
请用整个查询更新您的问题,这将有助于解决问题。
**更新bis**
1 2 3 4 5 6 7 8 9 | 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() |
应该是:
1 2 3 4 5 6 7 8 9 | 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() |
检查组是否有第一个,如果没有,则该组没有任何记录,因此操作。时间戳的名称没有可发送的电子邮件。如果第一个不为空,则循环抛出group元素并创建电子邮件列表,
为了响应您的更新,要创建空列表,您可以在分配
1 2 3 4 5 6 7 8 9 10 11 |
- 这里有一个dotnetfiddle试图做你想做的事情。https://dotnetfidle.net/kgjvje
- 下面是基于您的评论的后续dotnettle。https://dotnetfidle.net/h2xd9o
作为对您的评论的回应,上面的内容适用于linq-to对象,但不适用于linq-to-sql。linq-to-sql会抱怨它,"无法翻译表达式…"这是因为Linq无法将自定义的
我想我们已经充分回答了你关于左连接的原始问题。考虑问一个关于在LinqToSQL查询中使用自定义方法/构造函数的新问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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模型类型。