这是表
public class Purchase
{
public long Id { get; set; }
public string WareName { get; set; }
public int Count { get; set; }
public DateTime BuyTime { get; set; }
public IList<Inventory> Inventory { get; set; }
}
public class Inventory
{
public long Id { get; set; }
public long PurchaseId { get; set; }
[ForeignKey(nameof(PurchaseId))]
public Purchase Purchase { get; set; }
public int SaledCount { get; set; }
}
我尝试像这样进行查询:
SELECT SUM(x.[icout]) AS icount FROM
(
SELECT p.[Count] - ISNULL(
(SELECT SUM(i.SaledCount) FROM Inventory AS i WHERE i.PurchaseId = p.Id )
,0) AS [icout]
FROM Purchase AS p
WHERE p.WareName ='WareName5' AND
(
p.[Count] - ISNULL((SELECT SUM(i.SaledCount) FROM Inventory AS i WHERE i.PurchaseId = p.Id ),0) > 0
)
) AS x`
var left = _Db.Set<Purchase>().Include(p=>p.Inventory)
.Where(p=>p.WareName == WareName)
.Select(p => p.Count - p.Inventory.Sum(i => i.SaledCount)).Sum();
但是当我定位一个真正的数据库(sqlite / sqlserver)时它不起作用。 当我使用inMemoryDatabase时,它工作正常。 有谁可以帮助我?
答案 0 :(得分:0)
好的,这只是尝试使用let
,只是在我的DNet Core网站上尝试过,它运行得很好(我当然没有和你一样的实体)。
var left = from purchase in _Db.Set<Purchase>().Include(p=>p.Inventory)
where purchase != null && purchase.WareName == WareName
let sum = purchase.Inventory.Sum(i => i.SaledCount ?? 0)
select (purchase.Count - sum).Sum();'
这是一个直截了当的解决方案,不应该给你一个N + 1问题。 它解决了内存中的“复杂”解决方案。有时成本必须在某个地方,并且在内存中总和优于N + 1
var left = (from purchase in _Db.Set<Purchase>().Include(p=>p.Inventory)
where purchase != null && purchase.WareName == WareName
select new ()
{
count = purchase.Count - sum,
invCounts = purchase.Inventory.where(a=> a.SaledCount!= null).Select(a=> a.SaledCount);
}).ToList().Select(a => a.count - invCounts.Sum());
注意强>
使用ICollection
代替IList
,因为它的功能可以更好地转换为SQL
同样在构造函数中将集合初始化为new HashSet<T>()
,因此您不会以null异常结束。可以这样想,你不能计算null
的元素,但你可以用0行计算集合的元素。
public class Purchase
{
public Purchase(){
Inventory = new HashSet<Inventory>();
}
public ICollection<Inventory> Inventory { get; set; }
}