C# Linq查询中的左连接
我试图在linq查询中进行左连接,而不是内部连接。我已经找到了与使用C# Linq查询中的左连接,c#,linq,entity-framework,join,left-join,C#,Linq,Entity Framework,Join,Left Join,我试图在linq查询中进行左连接,而不是内部连接。我已经找到了与使用DefaultIfEmpty()相关的答案,但我似乎无法让它工作。以下是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 } i
DefaultIfEmpty()
相关的答案,但我似乎无法让它工作。以下是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的多个子对象中列出0-n个对应记录的列表
更新:
我试图回答下面提到的“可能重复”的问题。现在我有了下面的代码,即使没有Table2记录,表1中的每个项目也会有一条记录
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”为空。为了回复您的更新,要创建空列表,您可以在
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();
- 这里有一个dotnetfiddle,它试图做你正在尝试的事情李>
- 下面是基于您的评论的后续dotnetfiddle李>
新子对象
构造函数转换为SQL。要做到这一点,您必须编写更多代码来支持转换为SQL。见和
我想我们已经充分回答了您关于左连接的原始问题。考虑在LINQ to SQL查询中使用自定义方法/构造函数的一个新问题。 < P>我认为您想要的结果可以通过使用给出。 下面的代码将生成这样的结构 字段1,字段2,列表<子对象>空 示例代码
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();
网络小提琴
更新
从你的评论中我看到了这一点
ga.Select(g = > new SubObject(){fielda = g.fielda, fieldb = g.fieldb})
我认为应该是(取决于“ga”是如何构建的)
请用整个查询更新您的问题,这将有助于解决问题
**更新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()
sentmails=//ga.Count()<1?无效的:
//(从ga中的g中选择g).FirstOrDefault()==null?无效的:
(从ga中的g选择新电子邮件{
email\u to=g.email\u to,
email\u from=g.email\u from,
email\u cc=g.email\u cc,
email\u bcc=g.email\u bcc,
电子邮件主题=g.电子邮件主题,
email\u body=g.email\u 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()
sentmails=//ga.Count()<1?无效的:
((从ga中的g选择g).FirstOrDefault()==null)?无效的:
(从ga中的g选择新电子邮件{
email\u to=g.email\u to,
email\u from=g.email\u from,
email\u cc=g.email\u cc,
email\u bcc=g.email\u bcc,
电子邮件主题=g.电子邮件主题,
email\u body=g.email\u body}).ToList()
检查组是否有第一次,如果没有,则组没有任何记录,因此时间戳的Action.Name没有可发送的电子邮件。如果第一个不为空,循环将抛出组元素并创建电子邮件列表
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模型类型。当表2中没有值时,我应该添加可能的副本。许多子对象应该为空。我在上面的问题中尝试过,结果包含所有记录,这是一个改进,但是当表2中没有记录时,我得到一个实例化的子对象,其中包含所有空值。如果表2中没有值,我真正想要的是“manySubObjects”为null。我认为我的答案中的三元表示您最近关于需要“manySubObjects”为null的评论。Net Fiddle谢谢。GroupJoin()确实是一个更整洁的查询。我得到的
表达式无法将“ga.Select(g=>newsubobject(){fielda=g.fielda,fieldb=g.fieldb})”转换为SQL,并且无法将您的答案视为与Shaun的答案相同的本地表达式
异常。我看不出我所做的与你所做的有什么不同…用你的问题的副本更新你的问题你为什么检查组中的第一个元素是否为空?如果您的组中没有任何项目,它将如何创建电子邮件实体我尝试了这个方法,但是,我收到一个错误,错误是无法将表达式“ga.Select(g=>new SubObject(){fielda=g.fielda,fieldb=g.fieldb}”转换为SQL,并且无法将其视为本地表达式。知道是什么导致了这个错误吗?我找不到我的代码和你的代码有什么不同…@kralco626可能是你的代码中的=>
部分在等号和尖括号之间有一个空格。我的代码中根本没有“=>”。它一定是在将我的代码编译成那种格式?在你的回答中,如果我注释掉行(从ga中的g选择g)。FirstOrDefaut()==null?null:
错误消失了(很明显,查询没有按我所希望的那样运行)。因此,这行代码的构造方式与它不一样…@kralco626可以发表一条评论,链接到您的代码的dotnetfiddle。这样我就可以查看您的代码。那样比较容易。
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();