如何在LINQ Select Sum中设置零值而不是null

时间:2017-04-15 19:27:35

标签: c# sql-server entity-framework linq

我尝试使用LINQ到我的EF Code First数据库进行查询以检索全年的销售额并返回一个新的DTO对象,该对象包含月份数和当月销售总额。

我的查询工作正常,但不包含销售的月份会返回null而不是“0”,这会在我的视图中产生问题。

我已经尝试了空合并??,但得到的编译错误对decimal无效。我也尝试了DefaultIfEmpty,但这似乎与.Sum-method一起使用。

有什么建议吗?

型号:

public class YearlySalesDto
{
    public string Month { get; set; }
    public decimal TotalSales { get; set; }
}

查询:

[AllowAnonymous]
public IEnumerable<YearlySalesDto> Index()
{
    var result = from r in db.Orders
                 group r by r.OrderDate.Month into g
                 select new YearlySalesDto { Month = g.Key.ToString() ?? "", TotalSales = g.Sum(p => p.OrderItems.Select(x => x.Quantity * x.UnitPrice).Sum()) };

    if (result == null)
    {
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
    }

    return result;
}

此查询的结果,因为我在第3个月和第4个月只在数据库中有销售。

[
  {
    "Month": "3",
    "TotalSales": 158
  },
  {
    "Month": "4",
    "TotalSales": 373
  }
]

2 个答案:

答案 0 :(得分:4)

你的选择与此问题无关,你可以摆脱它并仍然看到问题,GroupBy不返回g.Count == 0的值,你需要做的是添加占位符条目对于db.Orders中没有行的月份,总计为0,并将其与结果合并。

var result = from r in db.Orders
             group r by r.OrderDate.Month
             into g
             select new YearlySalesDto { 
                Month = g.Key.ToString(), // The  ?? "" is unnecessary. 
                TotalSales = g.Sum(p => p.OrderItems.Select(x => x.Quantity * x.UnitPrice).Sum()) 
            };

var fixedResult = result.AsEnumerable()
                        .Union(Enumerable.Range(1,12)
                                         .Select(x=>new YearlySalesDto { Month = x.ToString(), TotalSales = 0 })
                               , new MonthComparer());


//Elsewhere
class MonthComparer : IEqualityComparer<YearlySalesDto>
{
    public bool Equals(YearlySalesDto x, YearlySalesDto y)
    {
        return x.Month == y.Month;
    }
    public int GetHashCode(YearlySalesDto x)
    {
        return x.Month.GetHashCode();
    }
}

答案 1 :(得分:3)

您收到的编译错误由@Scott在上面的评论中解释。

至于数月的零值,数据库中没有剩下的数据,请将结果与月份集合连接,如果是null地点0

var result = from m in Enumerable.Range(1,12)
             join g in db.Orders.GroupBy(r => r.OrderDate.Month) on m equals g.Key into joint
             from g in joint.DefaultIfEmpty()
             select new YearlySalesDto { 
                 Month = m.ToString(),
                 TotalSales = g == null ? 0 :  g.Sum(p => p.OrderItems.SelectMany(x => x.Quantity * x.UnitPrice))
             };