C# LINQ连接和外部连接-如何将SQL转换为LINQ表达式
我想将以下SQL查询转换为LINQ表达式(使用EntityFramework 6.1)。到目前为止,我还无法找到一个可接受的LINQ表达式来产生类似的结果。如果您能帮助我们将这个简单的SQL语句转换成LINQ express,我们将不胜感激C# LINQ连接和外部连接-如何将SQL转换为LINQ表达式,c#,sql,linq,linq-to-sql,entity-framework-6,C#,Sql,Linq,Linq To Sql,Entity Framework 6,我想将以下SQL查询转换为LINQ表达式(使用EntityFramework 6.1)。到目前为止,我还无法找到一个可接受的LINQ表达式来产生类似的结果。如果您能帮助我们将这个简单的SQL语句转换成LINQ express,我们将不胜感激 SELECT AAG.Id AS GroupId, A.Id AS ActivityId, A.Title As Title, CASE WHEN AA.CompletedOn IS NULL THEN CAST(1 AS bit) ELS
SELECT AAG.Id AS GroupId,
A.Id AS ActivityId,
A.Title As Title,
CASE WHEN AA.CompletedOn IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS Completed,
COALESCE(AAG.PointValue, 0) + SUM(COALESCE(AQ.PointValue, 0)) AS PointTotal
FROM ActivityAssignmentGroup AAG
INNER JOIN ActivityAssignment AA ON AA.GroupId = AAG.Id
INNER JOIN Activity A ON AA.ActivityId = A.Id
LEFT OUTER JOIN ActivityQuestion AQ ON AQ.ActivityId = A.Id
WHERE AAG.AssignedToId = 6
GROUP BY AAG.Id, A.Id, A.Title, CASE WHEN AA.CompletedOn IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END, COALESCE(AAG.PointValue,0)
如果没有左外部联接部分,下面的LINQ语句部分完成,但我无法找到添加左外部联接条件的适当语法:
var assignments = await (from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id
select new ActivityListViewModel
{
Id = a.Id,
Points = g.PointValue ?? 0,
Title = a.Title,
GroupId = g.Id,
Complete = (aa.CompletedOn != null)
});
编辑:
谢谢你的回复,鲍勃。我试图使用DefaultIfEmpty并查看实体框架生成的SQL查询结果,但它不起作用。在发表本文之前,以下是我尝试的LINQ声明:
var assignments = from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id
from aq in db.ActivityQuestions.Where(q => q.ActivityId == a.Id).DefaultIfEmpty()
group aq by new { ActivityId = aq.ActivityId, Title = a.Title, GroupId = g.Id, Points = g.PointValue ?? 0, Completed = (aa.CompletedOn != null) } into s
select new ActivityListViewModel
{
Id = s.Key.ActivityId,
Points = s.Key.Points + s.Sum(y => y.PointValue ?? 0), //g.PointValue ?? 0,
Title = s.Key.Title,
GroupId = s.Key.GroupId,
Complete = s.Key.Completed
};
当然,它也不起作用。结果是项目缺少Id(ActivityId)。您需要DefaultIfEmpty()将联接转换为MSDN中的左侧外部联接、文档
只是为了结束这个循环(谢谢你,鲍勃·维尔)。。。以下查询有效:
var assignments = from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id
from aq in db.ActivityQuestions.Where(q => q.ActivityId == a.Id).DefaultIfEmpty()
group aq by new { ActivityId = a.Id, Title = a.Title, GroupId = g.Id, Points = g.PointValue ?? 0, Completed = (aa.CompletedOn != null) } into s
select new ActivityListViewModel
{
Id = s.Key.ActivityId,
Points = s.Key.Points + s.Sum(y => y.PointValue ?? 0), //g.PointValue ?? 0,
Title = s.Key.Title,
GroupId = s.Key.GroupId,
Complete = s.Key.Completed
};
问题是按条件分组并使用ag.ActivityId,而我本应该使用a.Id.所以您只需要将外部联接添加到linq?听起来很直截了当。不知道为什么会有反对票。我也不知道反对票是什么。如果不是我花了很多时间想弄清楚的话,我是不会发帖子的。我想你应该使用
g.Id
而不是s.Key.ActvityID
Bob Vale-谢谢你的回复。我的原始查询可以正常工作,但尚未完成。我需要向ActivityQuestion集合添加一个联接。我想得到的是活动的总分数。积分可以应用于集团层面或活动层面(可能两者兼而有之,但实际上不太可能)。我添加了一个编辑来显示每个问题的分数总和。一个活动组可以有多个活动。一个活动可以(可选)有多个问题(0到1或更多)。最后的结果应该是一个活动列表和可能的要点。@Aggromonster查看paqogomez对您的问题的评论,您在groupby中使用了错误的id…再次感谢您。你是一位学者和绅士。真不敢相信我没早点发现。看起来我的查询是对的,但加入分配失败。
var assignments = from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id
from aq in db.ActivityQuestions.Where(q => q.ActivityId == a.Id).DefaultIfEmpty()
group aq by new { ActivityId = a.Id, Title = a.Title, GroupId = g.Id, Points = g.PointValue ?? 0, Completed = (aa.CompletedOn != null) } into s
select new ActivityListViewModel
{
Id = s.Key.ActivityId,
Points = s.Key.Points + s.Sum(y => y.PointValue ?? 0), //g.PointValue ?? 0,
Title = s.Key.Title,
GroupId = s.Key.GroupId,
Complete = s.Key.Completed
};