使用lambda表达式查询数据会得到令人不满意的结果

时间:2018-05-31 21:20:21

标签: c# sql asp.net-mvc lambda repository-pattern

鉴于以下sql查询工作正常,但当我将其转换为lamda表达式时,我在这一行上出错了

Expense = grp.Max(x => x.ex.TotalAmount.HasValue || x.ex.TotalAmount == 0 ? x.ex.TotalAmount : 0),

Error: Object reference not set to an instance of an object.

在lamda表达式中查询:

dbContext.PurchaseItems
  .Join(dbContext.WareHouses, pi => pi.WarehouseId, w => w.WareHouseId, (pi, w) => new { pi, w })
  .Join(dbContext.Products, pi => pi.pi.ProductId, p => p.ProductId, (pi, p) => new { pi, p })
  .Join(dbContext.Companies, pi => pi.pi.pi.CompanyId, c => c.CompanyId, (p, c) => new { p, c })
  .GroupJoin(dbContext.Expenses, pi => pi.p.p.ProductId, ex => ex.ProductId, (pi, ex) => new { pi, ex })
  .SelectMany(x => x.ex.DefaultIfEmpty(),
    (pi, ex) => new { pi, ex }
  )
  .ToList()
  .Where(x => x.pi.pi.c.CompanyId == getReport.CompanyId)
  .GroupBy(x => x.pi.pi.p.p.ProductId)
  .Select(grp => new
  {
     PurchaseItemPrice = Math.Round(ConversionHelper.SafeConvertToDouble(grp.Average(x => x.pi.pi.p.pi.pi.PurchaseItemPrice)), 2),
     WarehouseName = grp.Max(x => x.pi.pi.p.pi.w.WareHouseName),
     CompanyName = grp.Max(x => x.pi.pi.c.CompanyName),
     ProductName = grp.Max(x => x.pi.pi.p.p.ProductName),
     Expense = grp.Max(x => x.ex.TotalAmount.HasValue || x.ex.TotalAmount == 0 ? x.ex.TotalAmount : 0),
     ProductId = grp.Max(x => x.pi.pi.p.p.ProductId),
     AvailableQuantity = grp.Sum(x => x.pi.pi.p.pi.pi.AvailableQuantity),
  })
  .OrderBy(output => output.ProductId)
  .ToList();

在SQL中查询:

SELECT
 MAX(p.ProductId) AS ProductId,  
 MAX(p.ProductName) AS ProductName, 
 MAX(p.Productdescription) AS Productdescription,
 SUM((pt.PurchaseItemPrice) * pt.PurchaseItemQty) AS TotalPurchaseItemPrice,
 SUM(ex.TotalAmount) AS TotalExpense,
 AVG(pt.PurchaseItemPrice) AS UnitPurchaseItemPrice,
 SUM(pt.PurchaseItemQty) AS PurchaseItemQuantity,
 CAST(MAX(CAST(p.IsActive as INT)) AS BIT) AS IsActive,
 MAX(p.CreatedBy) AS CreatedBy,
 MAX(p.CreatedDate) AS CreatedDate,
 MAX(pt.WareHouseId) AS WareHouseId
FROM [Product] p 
INNER JOIN purchaseItem pt on p.ProductId = pt.ProductId
LEFT  JOIN Expense      ex on p.ProductId = ex.ProductId
INNER JOIN WareHouse wh on wh.WareHouseId = pt.WareHouseId
INNER JOIN Company   c  on c.CompanyId    = pt.CompanyId
WHERE p.CompanyId = 1
GROUP BY p.ProductId

我正在使用存储库设计模式,并且我使用lambda表达式来查询数据。请同时给出使用lambda表达式的最佳方法,因为在下面给出的代码中,可以很容易地看出我必须使用奇怪的方式编写代码,如 x.pi.pi.p.pi.w.WareHouseName 获取WareHouseName。

1 个答案:

答案 0 :(得分:0)

Expense = grp.Max(x => x.ex.TotalAmount.HasValue || x.ex.TotalAmount == 0 ? x.ex.TotalAmount : 0),

其实我犯了一个愚蠢的错误。我已将上面的行更改为以下给定的行并解决了问题。

Expense = grp.Sum(x => x.ex != null && x.ex.TotalAmount.HasValue ? x.ex.TotalAmount : 0)

错误已解决。但我也需要即兴创作我的代码。请有人建议我如何美化 x.pi.pi.p.pi.w.WareHouseName 声明。因为它看起来很奇怪