Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何通过子属性查询LINQ中的对象集合?_C#_Linq - Fatal编程技术网

C# 如何通过子属性查询LINQ中的对象集合?

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的所有订单 我试过很多方法。这两个查询

我是linq的新手,写两个简单的查询有困难。由于某种原因,我不能把我的头绕在它周围

这是一个简单的结构:订单包含OrderItems。每个orderItem都有一个productID

我想:

  • 获取订购productId 3的所有订单

  • var result = orders.Where(o => o.Items.Any(item => item.ProductId == 3));
    
  • 获取在同一订单上订购productId 4和productId 5的所有订单

  • 我试过很多方法。这两个查询位于小测试应用程序的底部

    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();
    }
    

    看起来跛脚鸭正在做“语言集成查询”版本,所以我不会这么做。

    我会这样做:

  • 获取订购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 == 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==3)&&
    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( );
        }