【问题标题】:C# Left join in LINQ [duplicate]LINQ中的C#左连接[重复]
【发布时间】:2014-04-09 02:26:46
【问题描述】:

不确定如何将以下 sql 转换为 LINQ 表达式。我的数据库确实使用了参照完整性,并且表 Content 与表 Content_Training 以一对多的关系相关(例如:1 个内容可以有多个 content_training)。

select c.ContentId, c.Name, ct.TrainingTypeId 
from dbo.Content c left join dbo.ContentTraining ct on c.ContentId = ct.ContentId
where c.ExpirationDate is not null
order by ct.TrainingTypeId, c.Name

我已经尝试过了,这似乎有效。但是,我不确定“let”关键字的用法。

var data = (from c in context.Contents
let ct = ( from t in context.Content_Training where t.ContentId == c.ContentId
select new { t.TrainingTypeId } ).FirstOrDefault()
where c.ExpirationDate.HasValue
orderby ct.TrainingTypeId, c.Name
select new { c.ContentId, c.Name, ct.TrainingTypeId } ).ToList();

【问题讨论】:

  • @第 8 位:添加了我迄今为止尝试过的内容。
  • 您的标题显示“左连接”,但您显示的 SQL 正在执行内部连接,所以我不清楚您要完成哪个操作。
  • Craig W:很抱歉。是的,我确实想要一个左连接。我编辑了我的 sql。
  • 您是不是在另一个用户名下问了完全相同的问题? stackoverflow.com/questions/22951644/…

标签: c# sql linq entity-framework


【解决方案1】:

对于左连接,你需要使用 DefaultIfEmpty()

您的查询应该类似于以下内容:

var query = from c in Content
            join ct in ContentTraining
            on c.ContentId equals ct.ContentId into g
            from ct in g.DefaultIfEmpty()
            where c.ExpirationDate != null
            select new
            {     
                c.ContentId, 
                c.Name, 
                ct.TrainingTypeId 
             }).ToList();

请参考Left outer join in linq

http://msdn.microsoft.com/en-us/library/bb397895.aspx

【讨论】:

  • 谢谢拉什米!关于下面 Craig W 的回答,“包含”是否进行了左连接?
  • 我不确定“包括”。也许克雷格可以回答。我的解决方案有效吗?我无法测试它,因为我现在没有 VS.Net。
【解决方案2】:

或者,您可以考虑使用 lambda 而不是表达式语法。我没有尝试过,但这应该可以满足您的需求(如果您需要的是左连接)。

var foo = context.Contents.Include( "Content_Training" )
    .Where( c => c.ExpirationDate != null )
    .OrderBy( c => c.Content_Training.TrainingTypeId )
    .ThenBy( c => c.Name
    .Select( c => new { c.ContentId, c.Name, c.Content_Training.TrainingTypeId } );

【讨论】:

  • 那么“include”是左连接吗?
  • 另外,在这种情况下,我对 LINQ 版本感兴趣。我不确定我是否使用了“let”关键字,并希望得到一些相关信息和意见。
  • 它本身不是左连接,但结果基本相同,如果没有与 Content 对象关联的 Content_Training 对象,您仍然会得到 Content 对象。
【解决方案3】:

在 LINQ 中是:

from c in dbo.Content
join ct in dbo.ContentTraining on c.ContentId equals ct.ContentId
where c.ExpirationDate != null
orderby ct.TrainingTypeId, c.Name
select new
{
    ContentID = c.ContentId,
    Name = c.Name,
    TrainingTypeId = ct.TrainingTypeId
}

【讨论】:

  • 这不是内部连接示例吗?
  • 在你编辑你的问题之前,你有一个内部连接,因此我的回答。
  • 这与 OP 的要求不正确。他们想要 LINQ 中的 LEFT 联接,而不是 INNER JOIN。您上面的语句是 INNER JOIN。
猜你喜欢
  • 2021-05-06
  • 2017-09-28
  • 2017-04-10
  • 2023-03-19
  • 2014-07-29
  • 2015-06-20
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多