使用SUM、Case-When、Group-by、outer-join、aggregate和defaults的C#Linq到Sql查询

使用SUM、Case-When、Group-by、outer-join、aggregate和defaults的C#Linq到Sql查询,c#,sql,linq,linq-to-sql,c#-4.0,C#,Sql,Linq,Linq To Sql,C# 4.0,我一直在寻找可能的解决方案,并尝试了好几个小时,但运气不好。任何帮助都将不胜感激 我有一个Sql语句,我正试图把它组合成一个C#LINQ查询 以下是工作SQL: SELECT up.UserProfileID ,up.FirstName ,up.LastName ,SUM(CASE WHEN ul.CompletionDate IS NULL THEN 0 ELSE ISNULL(ul.Score, 0) END) AS TotalScore FR

我一直在寻找可能的解决方案,并尝试了好几个小时,但运气不好。任何帮助都将不胜感激

我有一个Sql语句,我正试图把它组合成一个C#LINQ查询

以下是工作SQL:

SELECT up.UserProfileID
    ,up.FirstName
    ,up.LastName
    ,SUM(CASE WHEN ul.CompletionDate IS NULL THEN 0
        ELSE ISNULL(ul.Score, 0)
    END) AS TotalScore
FROM dbo.UserProfile up
    LEFT OUTER JOIN dbo.UserLearning ul ON up.UserProfileID = ul.UserProfileID
WHERE up.ManagerUserProfileID IS NULL
GROUP BY up.UserProfileID, up.FirstName, up.LastName
我尝试了几种不同的方法,但似乎最终得到的是一个不返回所需内容的语句,或者没有成功执行

我当前的(非工作)代码如下所示:

var pd = from up in db.UserProfiles
     join ul in db.UserLearnings on up.UserProfileID equals ul.UserProfileID into temp
     from upJOINul in temp.DefaultIfEmpty(new UserLearning() { Score = 0 })

     where up.ManagerUserProfileID.Equals(null)

     group up by new
     {
         UserProfileID = up.UserProfileID,
         FirstName = up.FirstName,
         LastName = up.LastName,
         TotalScore = up.UserLearnings.Sum(u => u.Score)
     };

感谢您提供的任何帮助

不是您所要求的,但是如果您有一个工作复杂的SQL查询,它是相当静态的,请将其放在一个存储过程中,并将该SP拖到您的LINQ数据上下文中

LINQ提供程序必须在每次调用时将查询编译为sql,这需要时间和服务器CPU周期。如果是一个复杂的查询,它可能会占用大量资源。也可能会错过一些您可以使用直接SQL进行的优化

当然,除非有目的


如果您有ORM问题,请绘制实际的SQL命令,查看它,并与您想要实现的内容进行比较。您能否同时显示生成的SQL,以便我们更容易找到差异?

经过多次尝试和进一步使用google,我终于找到了一个可行的解决方案。我希望它对其他人有用

var pd = db.UserProfiles.AsEnumerable()
    .Where(up => up.ManagerUserProfileID.Equals(null))
    .Select(up => new
    {
        UserProfileID = up.UserProfileID,
        FirstName = up.FirstName,
        LastName = up.LastName,
        TotalScore = up.UserLearnings
            .Where(ul => ul.CompletionDate.HasValue && ul.Score.HasValue)
            .DefaultIfEmpty()
            .Sum(ul => ul != null && ul.Score.HasValue ? ul.Score : 0)
    });

谢谢你的快速回复。出于您提到的原因,我通常倾向于将复杂查询放在Sql中。然而,在这个项目中,性能的优先级非常低,最好在代码中保留这样的逻辑。我在几分钟内完成了sql代码,但我仍在学习LINQ,这是我希望能够解决这个问题的另一个原因。。。简单地了解一下我自己关于显示生成的Sql的情况,我现在使用的C代码给了我这个运行时错误:“实体或复杂类型‘CPDModel.UserLearning’不能在LINQ to Entities查询中构造”我猜
DefaultIfEmpty(new UserLearning(){Score=0})
部分是该错误的原因。但即使只留下一个
DefaultIfEmpty()
,它也应该可以工作,因为它应该转换为一个左连接和求和,sql应该注意它。如果我只按照建议使用DefaultIfEmpty(),代码确实会运行,但我在其中一个结果上得到的TotalScore结果为null。它也没有考虑完工日期,而且总数也不正确。阿科斯,这有点太多的猜测和‘应该’=)还有其他人有什么建议吗?