我有以下架构:
product
- productID (PK)
- name
- units
purchase
- purchaseID (PF)
- productID (FK)
- soldUnits
- woUnits
boxContents
- boxID (PK)
- puchaseID (FK)
- count
以及以下Linq to SQL查询:
var qStockLevel = from pr in db.products
select new
{
pr.productID,
pr.name,
totalUnits = (from pu in db.purchases
where pu.productID == pr.productID
select pu).Count() * pr.units,
sold = (from pr2 in db.products
join pu in db.purchases on pr.productID equals pu.productID into pp
where pr2.productID == pr.productID
from pu2 in pp.DefaultIfEmpty()
select (int?) pu2.soldUnits ?? 0).Sum(),
writtenOff = (from pr2 in db.products
join pu in db.purchases on pr.productID equals pu.productID into pp
where pr2.productID == pr.productID
from pu in pp.DefaultIfEmpty()
select (int?)pu.woUnits ?? 0).Sum(),
onDisplay = (from pr2 in db.products
join bc in db.boxContents on pr.productID equals bc.purchase.productID into bp
where pr2.productID == pr.productID
from bc in bp.DefaultIfEmpty()
select (int?)bc.count ?? 0).Sum(),
available = (totalUnits - sold - writtenOff - onDisplay),
};
最后的“可用”列不起作用,但我已将其包含在内以说明我正在尝试实现的内容 - 根据已生成的列计算的列。这可能吗?我可以在表示层执行此操作,但想检查这是否可行。
另外 - 对于我的(Linq)新手来说,查询看起来效率低下,因为我正在重复生成writeOff和sold列。当我涉及聚合函数时,是否有更好的方法来实现这一点。
感谢。
修改
还有一件事 - 我只想返回“可用”是>的行。 0.
答案 0 :(得分:2)
这是一个应该做你想要的查询。
(注意:这假设您在DBML设计器中的Product
- > Purchases
- > BoxContents
之间设置了关联。)
var query = from product in context.Products
where
(
product.Purchases.Count() * product.units -
product.Purchases.Sum(purchase => purchase.soldUnits ?? 0) -
product.Purchases.Sum(purchase => purchase.woUnits ?? 0) -
product.Purchases.SelectMany(purchase => purchase.BoxContents).Sum(bc => bc.count ?? 0)
) > 0
select product;
而且,仅供参考,这是您设置Product
课程的一种方式。
(您可能希望使用DataLoadOptions.LoadWith()
来加载Product
的孩子。
public partial class Product
{
public int TotalUnits
{
get { return this.Purchases.Count * this.units ?? 0; }
}
public int Sold
{
get { return this.Purchases.Sum(p => p.soldUnits ?? 0); }
}
public int WrittenOff
{
get { return this.Purchases.Sum(p => p.woUnits ?? 0); }
}
public int OnDisplay
{
get { return this.Purchases.SelectMany(p => p.BoxContents).Sum(b => b.count ?? 0); }
}
public int Available
{
get { return TotalUnits - Sold - WrittenOff - OnDisplay; }
}
}
答案 1 :(得分:0)
为最后一行做第二次选择新{}(你必须再次复制你在第二次选择中需要的所有字段),然后添加一个where子句
编辑:没有真正相关,但看起来您可以从保留可用值的新列中受益(使用Linq To Sql和INotityPropertyChanging,它应该很容易实现)