繁体   English   中英

使用基于子项的Lambda / Linq过滤器父集合

[英]Using Lambda / Linq Filter Parent Collection based on Child Items

我有以下两节课;

public class Order
{
    public int Id {get;set;}
    public List<Item> Items {get;set;}
    public DateTime CreatedOn {get;set;}
}

public class Item
{
    public int Code {get;set;}
    public int SupplierId {get;set;}
    public string Name {get;set;}
    public decimal Price {get;set;}
}

我有一个订单列表,每个订单包含许多不同的项目。 我想过滤订单列表,以便实现以下目标;

  • 返回项目列表中至少有1个项目的SupplierId = 1的所有订单
  • 如果没有项目匹配SupplierId = 1,则不退回任何订单

UPDATE

我如何也可以扩展结果,以便只退回具有SupplierId = 1的订单和物料

这是我到目前为止尝试过的,现在可以使用。 但是如何进一步压缩它?

 List<Order> OrderList = new List<Order>();

 foreach(Order order in Order.Get(1))
 {
     Order tmpOrder = order;
     tmpOrder.Items = order.Items.Where(x => x.SupplierId == 1).ToList();

     if (tmpOrder.Items.Count > 0)
         OrderList.Add(tmpOrder );
  }

返回项目列表中至少有1个项目的SupplierId = 1的所有订单

如果没有项目匹配SupplierId = 1,则不退回任何订单

IEnuemrable<Order> orders = //...

var supplierOrders = orders.where(o => o.Items.Any(i => i.SupplierId == 1))
  .ToList();

似乎很简单。 除非您的意思是如果任何订单的SupplierId为1,则返回所有订单。

更新1

我如何也可以扩展结果,以便只退回具有SupplierId = 1的订单和物料

EF当前(据我所知,直到EF6)不允许您在单个查询中执行此操作。 考虑到EF所面临的笛卡尔积问题(有时),这仍然非常容易,并且实际上是有效的。

public class MyDbContext : DbContext
{ 
  DbSet<Order> Order { get; set; }
  DbSet<Item> Items { get; set; }
|

// each of these orders do not contain any
// items, we did not .Include() them.
var supplierOrders = db.Orders
  .Where(o => o.Items
               .Any(i => i.SupplierId == 1))
  .ToList();

var orderIds = supplierOrders
  .Select(so => so.Id)
  .ToList();

var supplierItems = db.Items.
  .Where(i => orderIds.Contain(i.SupplierId))
  .ToList();

因为我们使用的是EF上下文,只要您在EF中设置了正确的关系(我建议这样做),它将自动将联系人本地缓存的所有项目连接到任何关联的项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM