我有一个 LINQ 查询。在这方面,我需要做一些计算。一切都很好,除了在任何一个条件中找到空值时,它只是为整个条件返回空值。谁能告诉我,即使在条件中找到了一个空值,我如何返回某个值。
法典
var model =
(from q in db.Porders
select new porders()
{
Id = q.Id,
DetCount = (from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Id).Count(),
Amount = (from amtpord in db.Porders
where amtpord.Id == q.Id
select amtpord.Freight + amtpord.Misc - amtpord.Discount
).FirstOrDefault() +
(from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Copies * amtdet.EstUnitPrice
).Sum()
}).ToList();
我认为DefaultIfEmpty()
方法将是这里的解决方案
var model =
from q in db.Porders
select new porders()
{
DetCount =
db.PoDetails.Count(amtdet => amtdet.PoId == q.Id),
Amount =
(from amtpord in db.Porders
where amtpord.Id == q.Id
select amtpord.Freight + amtpord.Misc - amtpord.Discount)
.DefaultIfEmpty().First()
+
(from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Copies * amtdet.EstUnitPrice)
.DefaultIfEmpty().Sum()
}
尝试对可为空的列或FirstOrDefault
的结果应用合并column ?? 0
运算符(对于不满足条件的情况)。Linq to 实体会将此运算符转换为 SQL:
CASE WHEN Column IS NOT NULL THEN Column ELSE 0 END
它将看起来像:
var model =
(from q in db.Porders
select new porders()
{
Id = q.Id,
Amount = (from amtpord in db.Porders
where amtpord.Id == q.Id
select amtpord.Freight ?? 0 + amtpord.Misc ?? 0 - amtpord.Discount ?? 0
).FirstOrDefault() ?? 0 +
(from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Copies ?? 0 * amtdet.EstUnitPrice ?? 0
).Sum() ?? 0
}).ToList();
让我首先假设有一个导航属性Porder.Details
。接下来,为什么要在子查询中选择相同的Porder
?在我看来,您的查询可以简化为
from q in db.Porders
select new porders()
{
Id = q.Id,
DetCount = q.Details.Count(),
Amount = q.Freight + q.Misc - q.Discount
+ q.PoDetails.Select( d => d.Copies * d.EstUnitPrice)
.DefaultIfEmpty().Sum()
}
如果没有这样的导航属性,强烈建议创建一个。如果出于任何原因不能或不想这样做,则应在主查询 ( db.Porders.GroupJoin(db.PoDetails...)
) 中分组联接详细记录。
如果空值是由Freight
、Misc
或Discount
为空引起的,请使用运算符:q.Freight ?? 0
??
。