繁体   English   中英

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

[英]How do I query a collection of objects in LINQ by a child property?

我是linq的新手,无法编写两个简单的查询。 由于某种原因,我无法将头缠住它。

它的结构很简单:订单具有OrderItems。 每个orderItem都有一个productID。

我想要:

  1. 获取所有订购productId 3的订单

  2. 获取在同一订单上订购productId 4和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();
        }
    }
}

我会这样做:

  1. 获取所有订购productId 3的订单

     var result = orders.Where(o => o.Items.Any(item => item.ProductId == 3)); 
  2. 获取所有订购productId 4和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> GetOrdersWithProduct(int id)
{
    return orders.Where(o => o.Items.Any(item => item.ProductId == 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);

不使用Linq“语言集成查询”语法:

    public IEnumerable<Order> GetOrdersWithProduct(int productId)
    {
        List<Order> orders = OrderService.GetTestData();

        var result = orders.Where(o => o.Items.Any(i => i.ProductId == productId));

        return result.ToList();
    }

    public IEnumerable<Order> GetOrdersWithProduct(IEnumerable<int> productIds)
    {
        List<Order> orders = OrderService.GetTestData();

        var result = orders.Where(o => productIds.All(id => o.Items.Any(i => i.ProductId == id)));

        return result.ToList();
    }

看来Lame Duck正在执行“语言集成查询”版本,所以我不会这样做。

检查这些:

1。

from order in orders 
where order.Items.Exists(item => item.OrderItemId == 3)
select order
  1. 非常相似:

    从订单中order.Items.Exists(item => item.OrderItemId == 3)的订单开始
    order.Items.Exists(item => item.OrderItemId == 4)选择订单

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

暂无
暂无

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

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