2015-03-31 76 views
0

我有以下两个类;使用基于子项目的Lambda/Linq筛选器父集合

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项有供应商ID = 1
  • 不返回任何订单,如果没有项目匹配供应商ID = 1

UPDATE

如何扩展结果以便我只返回订单和具有SupplierId = 1的项目

这是wh在我尝试到目前为止,现在工作。但我怎样才能进一步压缩它;

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

到目前为止您尝试过哪些方面,以及您尝试解决方案时遇到了哪些问题?您的需求中的每一步都几乎准确地逐个映射到LINQ操作。 – Servy 2015-03-31 15:48:30

回答

5

返回所有订单,其中项目列表中至少1项有供应商ID = 1

不返回任何订单,如果没有项目匹配供应商ID = 1

IEnuemrable<Order> orders = //... 

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

看起来很直截了当。除非你的意思是返回所有的订单,如果任何顺序有1

更新一个供应商ID 1

如何展开的结果,这样我只返回订单和项目有供应商ID = 1

EF目前(据我所知EF6)不允许您在单个查询中执行此操作。考虑到EF面临的Cartesian Product问题(有时),它仍然非常容易并且实际上是高性能的。

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正确的关系设置(我建议做)线了任何项目的联系人缓存在本地任何相关的项目。

+0

只想返回包含Supplierid = 1的项目的订单。 – Tommassiov 2015-03-31 16:05:30

+0

这正是这样做的。 – 2015-03-31 16:34:12

+0

或者你的意思是你想要的订单包含带有SupplierId的项目,并且只有带有SupplierId = 1的项目。 – 2015-03-31 16:34:49