Linq三进制代码更好的解决方案

本文关键字:更好 解决方案 代码 Linq | 更新日期: 2023-09-27 18:11:49

我有一个开发人员写的代码。我认为这太可怕了,没有必要。

value = s.Businesses.SelectMany(
    x => x.Payments.Where(
        w => w.total != 0 && 
        !w.jobId.HasValue && 
        w.createdAt >= Utility.monthS 
        && w.createdAt <= Utility.monthE)
    ).Any() ? 
        s.Businesses.SelectMany(
            x => x.Payments.Where(
                w => w.total != 0 && 
                !w.jobId.HasValue && 
                w.createdAt >= Utility.monthS 
                && w.createdAt <= Utility.monthE)
            ).Sum(su => su.quantity) 
        : 0;

Sum之前执行.Any的原因是没有值的记录最终会获得空值并导致错误。

是否有更好的最佳实践方式来写这个

Linq三进制代码更好的解决方案

如果这不是为实体框架,那么Sum将只是返回0为空集合,你不需要做Any

value = s.Businesses.SelectMany(
    x => x.Payments.Where(
        w => w.total != 0 && 
             !w.jobId.HasValue && 
             w.createdAt >= Utility.monthS && 
             w.createdAt <= Utility.monthE))
    .Sum(su => su.quantity);

然而,因为这是实体框架,你有它被变成SQL和SUM在T-SQL将返回null为空集的问题。因此,您必须将最后一行替换为以下内容之一才能使其正常工作

.Sum(su => (int?)su.quanity) ?? 0;

.Select(su => su.quanity).DefaultIfEmpty().Sum();

第一个将告诉c#期望一个可能的null,如果是null则使用0。第二个将用一个默认值(在本例中为0)的集合替换空结果。

您不希望执行Any,然后执行Sum,因为这将导致对DB的两次调用。

在查询语法中是这样的:

var payments = 
  from x in s.Businesses
  from w in x.Payments
  where 
  w.total != 0 && 
  !w.jobId.HasValue && 
  w.createdAt >= Utility.monthS && 
  w.createdAt <= Utility.monthE
  select w;
value = 
payments.Any() ? payments.Sum(p => p.Quantity) : 0;

正如其他评论者评论的那样- Any()可能甚至没有必要,所以最后一行可以是value = payments.Sum(p => p.Quantity)