【发布时间】:2024-05-01 10:35:01
【问题描述】:
我正在尝试在 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 = 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 reference not set to an instance of an object。' m 为空。我不应该得到这个,因为我覆盖了空条目,或者我把这一切都弄错了?
【问题讨论】:
-
首先,使用您正在使用的数据层执行此操作(哪个?)。 LINQ to object 不同于 LINQ to SQL 提供程序。第二件事可能适用:使用导航属性,而不是
join。这样做 ORM 将 1. 取消空引用,因为它是 SQL 和 2. 自己找出左连接。 -
尝试以下操作:选择 grouped.Sum(m => (m == null) ? 0 :m.MinutesSpent).ToString()
-
也许我的SQL to LINQ Recipe 可以帮助你。您使用的是哪个 LINQ:LINQ to SQL / EF 6.x / EF Core 2.0 / 2.1 / 3.x / 5.x / 6.x?哪个数据库提供商?
-
在 LINQ to Objects(来自
DefaultIfEmpty())中,有时al将是null,在这种情况下,m将是null,而m.MinutesSpent将是NullReferenceException。对于 LINQ to Objects,您需要m?.MinutesSpent ?? 0。这与 LINQ to a database 不同。 -
@NetMage 你对 m 为空是正确的 - ` m?.MinutesSpent ?? 0`照顾它。您的 SQL to LINQ 配方正是我正在寻找的!