asp.net MVC 3 - 如何以更好的方式编写此 Linq 查询以返回总和



我有一个 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...) ) 中分组联接详细记录。

如果空值是由FreightMiscDiscount为空引起的,请使用运算符:q.Freight ?? 0 ??

相关内容

  • 没有找到相关文章

最新更新