为了账号安全,请及时绑定邮箱和手机立即绑定

来自不同表的两列的总和,如果辅助表没有任何数据,它应该返回结果

来自不同表的两列的总和,如果辅助表没有任何数据,它应该返回结果

C#
慕仙森 2022-12-04 11:08:58
我有两个表:Tb_PurchaseProductDetail(主键:id)、tb_productstockupdate(外键:PurchaseProductId(与 Tb_PurchaseProductDetail 表主键有关系))。现在我想要关系中 Tb_PurchaseProductDetail 表的两列值和 tb_productstockupdate 表的一列的总和 ()。如果 tb_productstockupdate 表中存在任何单行,但如果 tb_productstockupdate 表中没有可用数据,则下面的查询会给我正确的数据,而不是从主表返回数据。我希望如果辅助表中不存在数据,至少它应该基于主表返回数据。s.tb_productstockupdate.Sum(d => d.StockDifference))上面的代码应该返回 0 而不是 null。下面是我正在使用的代码。我不知道我错过了什么。connectionObj.Tb_PurchaseProductDetail.Where(s => s.ProductId == prodcutId && ((s.Quantity + s.DiscountQuantity + s.tb_productstockupdate.Sum(d => d.StockDifference)) > s.SoldPackQuantity)).Select(s => new SelectListItem()            {                Text = s.BatchNumber + " [(" + (s.Quantity + s.DiscountQuantity + s.tb_productstockupdate.Sum(d => d.StockDifference) - s.SoldPackQuantity) + ") & " + s.ExpiryDate + "]",                Value = s.Id.ToString()            }).ToList();下面的代码解决了我的问题。我使用 Any() 检查辅助表是否有数据,并相应地放置我的逻辑。connectionObj.Tb_PurchaseProductDetail.Where(s => s.ProductId == prodcutId && ((s.Quantity + s.DiscountQuantity + (s.tb_productstockupdate.Any() ? s.tb_productstockupdate.Select(d => d.StockDifference).Sum() : 0)) > s.SoldPackQuantity)).Select(s => new SelectListItem()            {                Text = s.BatchNumber + " [(" + (s.Quantity + s.DiscountQuantity + (s.tb_productstockupdate.Any()? s.tb_productstockupdate.Sum(d => d.StockDifference) : 0) - s.SoldPackQuantity) + ") & " + s.ExpiryDate + "]",                Value = s.Id.ToString()            }).ToList();
查看完整描述

2 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

所以你有PurchaseProductsProductStocks,并且它们之间存在一对多关系:每个PurchaseProduct都有零个或多个ProductStocks,每个都ProductStock属于一个PurchaseProduct:外键PurchaseProductId指向的那个。

每个PurchaseProduct人也至少有两个属性,假设为 A 和 B。每个ProductStock人至少有一个属性 C。

要求:从每个 PurchaseProduct 及其所有 ProductStocks 中给我 A 和 B 及其所有 ProductStocks C 的总和

如果您遵循实体框架代码优先约定,您将得到类似于下面的内容

class PurchaseProduct

{

    public int Id {get; set;}


    public double A {get; set;}

    public double B {get; set;}

    ...


    // every PurchaseProduct has zero or more ProductStocks (one-to-many)

    public virtual ICollection<ProductStock> ProductStocks {get; set;}

}

class ProductStock

{

    public int Id {get; set;}

    public double C {get; set;}

    ...


    // every ProductStock belongs to exactly one PurchaseProduct, using foreign key

    public int PurchaseProductId {get; set;}

    public virtual PurchaseProduct PurchaseProduct {get; set;}

}

class MyDbContext : DbContext

{

     public DbSet<PurchaseProduct> PurchaseProducts {get; set;}

     public DbSet<ProductStock> ProductStocks {get; set;}

}

这就是实体框架检测表、表中的列、表之间的关系以及主键和外键所需知道的全部内容。


在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多,多对多,......)


定义了您的类后,您的查询就很简单了。


var result = myDbContext.PurchaseProducts

    .Where(purchaseProduct => ...)         // only if you don't want all PurchaseProducts


    // from every remaining PurchaseProduct calculate A + B + Sum(all C of its ProductStocks)

    .Select(purchaseProduct => purchaseProduct.A + purchaseProduct.B

            + purchaseProduct.ProductStocks

                             .Select(productStock => productStock.C)

                             .Sum());

实体框架知道 PurchaseProducts 和 ProductStocks 之间的关系,并且知道需要 groupJoin。


请注意,每个 purchaseProduct 都有一个 A 和一个 B。您将始终至少获得 A+B。如果 purchaseProduct 根本没有 ProductStocks,则 purchaseProduct.ProductStocks 将是一个空集合。Select 和 Sum 将产生零值。


有些人不信任实体框架,更喜欢自己加入群组:


var result = myDbContext.PurchaseProducts.GroupJoin(

    myDbContext.ProductStocks,


    purchaseProduct => purchaseProduct.Id,          // from every PurchaseProduct take the Id

    productStock => productStock.PurchaseProductId, // from every ProductStock take the foreign key


    // ResultSelector: from every PurchaseProducts, with all its matching ProductStocks

    // calculate A + B + Sum of all C of the productStocks

    (purchaseProduct, productStocksOfThisPurchaseProduct) =>

    purchaseProduct.A + purchaseProduct.B +

    productStocksOfThisPurchaseProduct.Select(productStock => productStock.C).Sum());

非常简单!


查看完整回答
反对 回复 2022-12-04
?
梦里花落0921

TA贡献1772条经验 获得超6个赞

下面的代码解决了我的问题。我使用 Any() 检查辅助表是否有数据,并相应地使用了三元运算符。


connectionObj.Tb_PurchaseProductDetail.Where(s => s.ProductId == prodcutId && ((s.Quantity + s.DiscountQuantity + (s.tb_productstockupdate.Any() ? s.tb_productstockupdate.Select(d => d.StockDifference).Sum() : 0)) > s.SoldPackQuantity)).Select(s => new SelectListItem()

            {

                Text = s.BatchNumber + " [(" + (s.Quantity + s.DiscountQuantity + (s.tb_productstockupdate.Any()? s.tb_productstockupdate.Sum(d => d.StockDifference) : 0) - s.SoldPackQuantity) + ") & " + s.ExpiryDate + "]",

                Value = s.Id.ToString()

            }).ToList();


查看完整回答
反对 回复 2022-12-04
  • 2 回答
  • 0 关注
  • 113 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信