C# 将具有左联接、组和求和的SQL转换为Linq查询
我试图在C&Linq中复制下面的SQL,但我对Linq的基本知识没有太多的经验C# 将具有左联接、组和求和的SQL转换为Linq查询,c#,linq,C#,Linq,我试图在C&Linq中复制下面的SQL,但我对Linq的基本知识没有太多的经验 SELECT SUM(coalesce(cd.minutesspent,0)) FROM timelabels t LEFT JOIN challengedetails cd on cd.createddate = t.date GROUP BY t.date 这将为每个日期提供分钟总数,如果有空条目,则为零。我觉得很简单 // timelabels structure DateTime start = Da
SELECT SUM(coalesce(cd.minutesspent,0))
FROM timelabels t
LEFT JOIN challengedetails cd on cd.createddate = t.date
GROUP BY t.date
这将为每个日期提供分钟总数,如果有空条目,则为零。我觉得很简单
// 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:“对象引用未设置为对象的实例。”
m为空。我不应该得到这个,因为我已经覆盖了空条目,或者我完全弄错了吗?在“实际代码”部分下,只需在求和函数中添加一个括号,如下所示 它应该注意null,甚至在Sum工作之前
select grouped.Sum(m => (m.MinutesSpent ?? 0)).ToString()
在“实际代码”部分下,只需在Sum函数中添加一个括号,如下所示 它应该注意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));
使用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));
首先,对正在使用的数据层执行此操作哪个?。LINQ to对象与LINQ to SQL提供程序不同。第二件可能适用的事情:使用导航属性,而不是连接。这样做ORM将1。取消空引用,因为它是SQL和2。找出左连接本身。尝试以下操作:选择grouped.Summ=>m==null?0:m.MinutesSpent.ToStringPerhaps我可能会帮助你。您使用的LINQ是:LINQ到SQL/EF 6.x/EF Core 2.0/2.1/3.x/5.x/6.x?哪一个数据库提供程序?有时al在来自DefaultIfEmpty的对象的LINQ中为null,在这种情况下,m为null,m.MinutesPent为NullReferenceException。你需要m?分钟的时间吗??0表示LINQ到对象。这与数据库的LINQ不同。@NetMage关于m为null的说法是正确的-`m?.MinutesSpent??0`处理它。您的SQL-to-LINQ配方也正是我想要的!首先,对正在使用的数据层执行此操作哪个?。LINQ to对象与LINQ to SQL提供程序不同。第二件可能适用的事情:使用导航属性,而不是连接。这样做ORM将1。取消空引用,因为它是SQL和2。找出左连接本身。尝试以下操作:选择grouped.Summ=>m==null?0:m.MinutesSpent.ToStringPerhaps我可能会帮助你。您使用的LINQ是:LINQ到SQL/EF 6.x/EF Core 2.0/2.1/3.x/5.x/6.x?哪一个数据库提供程序?有时al在来自DefaultIfEmpty的对象的LINQ中为null,在这种情况下,m为null,m.MinutesPent为NullReferenceException。你需要m?分钟的时间吗??0表示LINQ到对象。这与数据库的LINQ不同。@NetMage关于m为null的说法是正确的-`m?.MinutesSpent??0`处理它。您的SQL-to-LINQ配方也正是我想要的!