使用 Lambda / Linq Filter 基于子项的父集合
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;}
}
我有一个订单列表,每个订单都包含许多不同的项目。我想过滤订单列表,这样我就可以实现以下目标;
- Return 商品列表中至少有 1 件商品的 SupplierId = 1 的所有订单
- 如果没有任何项目匹配 SupplierId = 1,则不要 return 任何订单
更新
我怎样才能扩展结果,以便我只 return 具有 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 );
}
Return all orders where at least 1 item in the Item List has SupplierId = 1
Don't return any orders if no items match SupplierId = 1
IEnuemrable<Order> orders = //...
var supplierOrders = orders.where(o => o.Items.Any(i => i.SupplierId == 1))
.ToList();
看起来很简单。除非你的意思是 return ALL orders if ANY order has a supplierId of 1.
更新 1
How can I expand the results as well so that I only return orders and Items that have SupplierId = 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 中设置了正确的关系(我建议这样做),它就会自动将联系人在本地缓存的任何项目连接到任何关联项目。
我有以下两个类;
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;}
}
我有一个订单列表,每个订单都包含许多不同的项目。我想过滤订单列表,这样我就可以实现以下目标;
- Return 商品列表中至少有 1 件商品的 SupplierId = 1 的所有订单
- 如果没有任何项目匹配 SupplierId = 1,则不要 return 任何订单
更新
我怎样才能扩展结果,以便我只 return 具有 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 );
}
Return all orders where at least 1 item in the Item List has SupplierId = 1
Don't return any orders if no items match SupplierId = 1
IEnuemrable<Order> orders = //...
var supplierOrders = orders.where(o => o.Items.Any(i => i.SupplierId == 1))
.ToList();
看起来很简单。除非你的意思是 return ALL orders if ANY order has a supplierId of 1.
更新 1
How can I expand the results as well so that I only return orders and Items that have SupplierId = 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 中设置了正确的关系(我建议这样做),它就会自动将联系人在本地缓存的任何项目连接到任何关联项目。