繁体   English   中英

将具有左连接、分组和求和的 SQL 转换为 Linq 查询

[英]Converting an SQL with Left Join , Group and Sum to a Linq Query

我正在尝试在 C# 和 Linq 中复制以下 SQL,但我对 Z7FB528B61118DFE304CA Beyonds88 基础知识不太有经验。

SELECT SUM(coalesce(cd.minutesspent,0))
FROM timelabels t
LEFT JOIN challengedetails cd on cd.createddate = t.date 
GROUP BY t.date 

这会给我每个日期的分钟总和,如果有 null 条目,则为零。 我觉得很简单。

// timelabels structure 
DateTime start = DateTime.Now.AddDays(-14);
DateTime end = DateTime.Now;
List<DateTime> timelabels =  new List<DateTime>();
for (var dt = start; dt <= end; dt = dt.AddDays(1))
{
    timelabels.Add(dt);
}

// ChallengeDetails structure & sample data
class ChallengeDetails(){
    DateTime? Createddate
    int? MinutesSpent 
}
List<ChallengeDetails> ChallengeDetails = new List<ChallengeDetails >();
  List<ChallengeDetails> ChallengeDetails = new List<ChallengeDetails>();
            ChallengeDetails.Add(new ChallengeDetails { MinutesSpent = 44, Createddate = DateTime.Now.AddDays(-10) });
            ChallengeDetails.Add(new ChallengeDetails { MinutesSpent = 31, Createddate = DateTime.Now.AddDays(-7) });
            ChallengeDetails.Add(new ChallengeDetails { MinutesSpent = 13, Createddate = DateTime.Now.AddDays(-3) });
            ChallengeDetails.Add(new ChallengeDetails { MinutesSpent = 77, Createddate = DateTime.Now.AddDays(-2) });


// The Actual Code 
List<string> timedata = (from a in timelabels
                         join al in ChallengeDetails on a equals al.Createddate into All
                         from al in All.DefaultIfEmpty()
                         group al by a into grouped
                         select grouped.Sum(m => m.MinutesSpent ?? 0).ToString()
                        ).ToList();

看看这个它应该可以工作 - 我有 DefaultIfEmpty 应该复制左连接。 在总和内我有'?? 0' 这应该是没有 ChallengeDetail 的任何日期的后备。

但我得到 System.NullReferenceException:'对象引用未设置为 object 的实例。 m 是 null。 我不应该得到这个,因为我已经覆盖了 null 条目,还是我把这一切都弄错了?

在“实际代码”部分下,只需在 Sum function 中添加一个括号,如下所示它应该注意 null,甚至在 Sum 工作之前。

select grouped.Sum(m => (m.MinutesSpent ?? 0)).ToString()

这将为您做,使用 LINQ - Lambda 表达式:

var TotalMinutesSpentGroupedList = timelabels
         .GroupJoin(challengedetails,
                    t => date,
                    cd => createddate,
                    (t,cd) => new 
                    { 
                       MinutesSpent = cd.minutesspent ?? 0,
                       CreateDate = cd.createddate ?? DateTime.Now
                    })
         .SelectMany(tcd=> challengedetails.DefaultIfEmpty(),
                     (t, cd) => new 
                     { 
                        MinutesSpent = cd.minutesspent ?? 0,
                        CreateDate = cd.createddate ?? DateTime.Now
                     })
         .Select(s => new 
                     { 
                        MinutesSpent = cd.minutesspent ?? 0,
                        CreateDate = cd.createddate ?? DateTime.Now
                     })
         .GroupBy(g => g.createddate).Select(item => item.Sum(s => s.minutesspent));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM