Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ连接和外部连接-如何将SQL转换为LINQ表达式_C#_Sql_Linq_Linq To Sql_Entity Framework 6 - Fatal编程技术网

C# LINQ连接和外部连接-如何将SQL转换为LINQ表达式

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

我想将以下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) 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
                          };