C# 如何通过子属性查询LINQ中的对象集合?
我是linq的新手,写两个简单的查询有困难。由于某种原因,我不能把我的头绕在它周围 这是一个简单的结构:订单包含OrderItems。每个orderItem都有一个productID 我想:C# 如何通过子属性查询LINQ中的对象集合?,c#,linq,C#,Linq,我是linq的新手,写两个简单的查询有困难。由于某种原因,我不能把我的头绕在它周围 这是一个简单的结构:订单包含OrderItems。每个orderItem都有一个productID 我想: 获取订购productId 3的所有订单 var result = orders.Where(o => o.Items.Any(item => item.ProductId == 3)); 获取在同一订单上订购productId 4和productId 5的所有订单 我试过很多方法。这两个查询
var result = orders.Where(o => o.Items.Any(item => item.ProductId == 3));
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace test
{
class Program
{
static void Main(string[] args)
{
OrderService svc = new OrderService();
//find all orders that purchased ProductID 3
IEnumerable<Order> data = svc.GetOrdersWithProduct(3);
//find all orders that purchase product 4 AND 5
IEnumerable<Order> data2 = svc.GetOrdersWithProduct(new int[] { 4, 5} );
}
}
public class Order
{
public int OrderId { get; set; }
public IEnumerable<OrderItem> Items { get; set; }
}
public class OrderItem
{
public int OrderItemId { get; set; }
public int OrderId { get; set; }
public int ProductId { get; set; }
}
public class OrderService
{
private static List<Order> GetTestData()
{
List<Order> orders = new List<Order>();
//5 Orders, 3 items each (every orderitem has a unique product in this test set)
int orderitemid = 1;
int productid = 1;
for (int orderid = 1; orderid < 6; orderid++)
{
orders.Add(new Order
{
OrderId = orderid,
Items = new List<OrderItem>
{
new OrderItem() { OrderId = orderid, OrderItemId = orderitemid++, ProductId = productid ++ },
new OrderItem() { OrderId = orderid, OrderItemId = orderitemid++, ProductId = productid ++ },
new OrderItem() { OrderId = orderid, OrderItemId = orderitemid++, ProductId = productid ++ }
}
});
}
return orders;
}
public IEnumerable<Order> GetOrdersWithProduct(int productId)
{
List<Order> orders = OrderService.GetTestData();
// ?? not really what i want, since this returns only if all items are the same
var result = orders.Where(o => o.Items.All(i => i.ProductId == productId));
return result.ToList();
}
public IEnumerable<Order> GetOrdersWithProduct(IEnumerable<int> productIds)
{
List<Order> orders = OrderService.GetTestData();
//??
var result = orders.Where(o => o.Items.All(productIds.Contains(i => i.ProductId)));
return result.ToList();
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
名称空间测试
{
班级计划
{
静态void Main(字符串[]参数)
{
OrderService svc=新的OrderService();
//查找购买ProductID 3的所有订单
IEnumerable data=svc.GetOrdersWithProduct(3);
//查找购买产品4和5的所有订单
IEnumerable data2=svc.GetOrdersWithProduct(新的int[]{4,5});
}
}
公共阶级秩序
{
公共int-OrderId{get;set;}
公共IEnumerable项{get;set;}
}
公共类OrderItem
{
公共整型OrderItemId{get;set;}
公共int-OrderId{get;set;}
public int ProductId{get;set;}
}
公共类订购服务
{
私有静态列表GetTestData()
{
列表顺序=新列表();
//5个订单,每个订单3个项目(每个订单项目在此测试集中都有一个唯一的产品)
int orderitemid=1;
int productid=1;
for(int-orderid=1;orderid<6;orderid++)
{
订单。添加(新订单)
{
OrderId=OrderId,
项目=新列表
{
new OrderItem(){OrderId=OrderId,OrderItemId=OrderItemId++,ProductId=ProductId++},
new OrderItem(){OrderId=OrderId,OrderItemId=OrderItemId++,ProductId=ProductId++},
new OrderItem(){OrderId=OrderId,OrderItemId=OrderItemId++,ProductId=ProductId++}
}
});
}
退货订单;
}
公共IEnumerable GetOrdersWithProduct(int productId)
{
List orders=OrderService.GetTestData();
//??并非我真正想要的,因为只有当所有项目都相同时才会返回
var result=orders.Where(o=>o.Items.All(i=>i.ProductId==ProductId));
返回result.ToList();
}
公共IEnumerable GetOrdersWithProduct(IEnumerable ProductId)
{
List orders=OrderService.GetTestData();
//??
var result=orders.Where(o=>o.Items.All(ProductId.Contains(i=>i.ProductId));
返回result.ToList();
}
}
}
不带Linq“语言集成查询”语法:
public IEnumerable GetOrdersWithProduct(int-productId)
{
List orders=OrderService.GetTestData();
var result=orders.Where(o=>o.Items.Any(i=>i.ProductId==ProductId));
返回result.ToList();
}
公共IEnumerable GetOrdersWithProduct(IEnumerable ProductId)
{
List orders=OrderService.GetTestData();
var result=orders.Where(o=>ProductId.All(id=>o.Items.Any(i=>i.ProductId==id));
返回result.ToList();
}
看起来跛脚鸭正在做“语言集成查询”版本,所以我不会这么做。我会这样做:
var result = orders.Where(o => o.Items.Any(item => item.ProductId == 3));
var result = orders.Where(o => o.Items.Any(item => item.ProductId == 4))
.Where(o => o.Items.Any(item => item.ProductId == 5));
public static IEnumerable<Order> GetOrdersWithProducts(params int[] ids)
{
return GetOrdersWithProducts((IEnumerable<int>) ids);
}
public static IEnumerable<Order> GetOrdersWithProducts(IEnumerable<int> ids)
{
return orders.Where(o => !ids.Except(o.Items.Select(p => p.ProductId))
.Any());
}
var result1 = GetOrdersWithProducts(3);
var result2 = GetOrdersWithProduct(4, 5);
公共静态IEnumerable GetOrdersWithProducts(参数int[]id)
{
返回GetOrdersWithProducts((IEnumerable)ID);
}
公共静态IEnumerable GetOrdersWithProducts(IEnumerable ID)
{
退货订单。其中(o=>!id.Except(o.Items.Select(p=>p.ProductId))
.Any());
}
var result1=GetOrdersWithProducts(3);
var result2=GetOrdersWithProduct(4,5);
查看以下内容:
一,
order.Items.Exists(item=>item.OrderItemId==4) 选择订单
public IEnumerable GetOrdersWithProduct(int-productId)
{
List orders=OrderService.GetTestData();
//??并非我真正想要的,因为只有当所有项目都相同时才会返回
//var result=orders.Where(o=>o.Items.All(i=>i.ProductId==ProductId));
var result=orders.Where(o=>o.Items.Any(ii=>ii.ProductId==ProductId));
返回result.ToList();
}
在什么情况下“没有LINQ”?其中/All/Any是所有LINQ方法。你是说“不使用查询表达式语法”吗?是的,对不起,我是说没有linq集成查询。在我的大多数C#2.0代码中已经有了这样的方法(只有一些名称差异,如Map/Reduce作为Select/Aggregate,显然不是作为扩展方法),因此我很难在这里看到任何特定于“linq”的方法,它们只是一些基本函数的方便的默认定义。事实上,它们在系统中。Linq名称空间对我来说似乎有点轶事。太好了,谢谢!我想我离这里不远了。是否有办法使OrderItems集合仅具有匹配的ProductID?假设我想要一个订单集合,其中每个订单中只有OrderItems与我传入的ProductId相等。您的意思是要筛选出任何包含其他产品的订单,还是要创建订单的新副本,但仅包含相关产品?创建新副本
var result1 = GetOrdersWithProduct(3);
var result2 = GetOrdersWithProduct(4).Intersect(GetOrdersWithProduct(5));
public static IEnumerable<Order> GetOrdersWithProducts(params int[] ids)
{
return GetOrdersWithProducts((IEnumerable<int>) ids);
}
public static IEnumerable<Order> GetOrdersWithProducts(IEnumerable<int> ids)
{
return orders.Where(o => !ids.Except(o.Items.Select(p => p.ProductId))
.Any());
}
var result1 = GetOrdersWithProducts(3);
var result2 = GetOrdersWithProduct(4, 5);
from order in orders
where order.Items.Exists(item => item.OrderItemId == 3)
select order
public IEnumerable<Order> GetOrdersWithProduct( int productId )
{
List<Order> orders = OrderService.GetTestData( );
// ?? not really what i want, since this returns only if all items are the same
//var result = orders.Where( o => o.Items.All( i => i.ProductId == productId ) );
var result = orders.Where(o => o.Items.Any(ii => ii.ProductId == productId));
return result.ToList( );
}