C# LINQ-筛选器子集合

C# LINQ-筛选器子集合,c#,linq,C#,Linq,我希望能够查询父实体并筛选子集合的内容 例如,我有一个OrderHeader集合。我希望使用LINQ查询此集合以返回所有OrderHeader,但我只希望包含一些相关的OrderDetail行 我最好是寻找一个解决方案,我可以在一个LINQ语句中完成所有这一切 下面的控制台应用程序演示了这一点 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ

我希望能够查询父实体并筛选子集合的内容

例如,我有一个OrderHeader集合。我希望使用LINQ查询此集合以返回所有OrderHeader,但我只希望包含一些相关的OrderDetail行

我最好是寻找一个解决方案,我可以在一个LINQ语句中完成所有这一切

下面的控制台应用程序演示了这一点

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LINQ
{
    class Program
    {
        static void Main(string[] args)
        {
            List<OrderHeader> orders = GetOrderHeaders();

            var filteredOrders = from p in orders
                                 where p.Detail.Where(e => e.StockCode == "STK2").Count() > 0
                                 select p;

            foreach (var order in filteredOrders)
            {
                Console.WriteLine("Account {0} ", order.AccountCode);

                foreach (var detail in order.Detail)
                {
                    Console.WriteLine("StockCode {0}, Quantity {1}", detail.StockCode, detail.Quantity);
                }

                Console.WriteLine();
            }

            // The above will return the following:
            // Account CUST1
            // StockCode STK1, Quantity 1
            // StockCode STK2, Quantity 2
            //
            // Account CUST2
            // StockCode STK2, Quantity 1
            // StockCode STK4, Quantity 2

            // How can I get the following?
            // Account CUST1
            // StockCode STK2, Quantity 2
            //
            // Account CUST2
            // StockCode STK2, Quantity 1

            Console.ReadLine();
        }

        public static List<OrderHeader> GetOrderHeaders()
        {
            List<OrderHeader> orders = new List<OrderHeader>();

            OrderHeader header = 
                new OrderHeader { 
                    AccountCode = "CUST1", 
                    Detail = new List<OrderDetail>()};
            header.Detail.Add(
                new OrderDetail { StockCode = "STK1", Quantity = 1 });
            header.Detail.Add(
                new OrderDetail { StockCode = "STK2", Quantity = 2 });
            orders.Add(header);

            header =
                new OrderHeader
                {
                    AccountCode = "CUST2",
                    Detail = new List<OrderDetail>()
                };
            header.Detail.Add(
                new OrderDetail { StockCode = "STK2", Quantity = 1 });
            header.Detail.Add(
                new OrderDetail { StockCode = "STK4", Quantity = 2 });
            orders.Add(header);

            return orders;
        }
    }

    public class OrderHeader
    {
        public string AccountCode { get; set; }
        public List<OrderDetail> Detail {get; set;}
    }

    public class OrderDetail
    {
        public string StockCode { get; set; }
        public int Quantity { get; set; }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
名称空间LINQ
{
班级计划
{
静态void Main(字符串[]参数)
{
List orders=GetOrderHeaders();
var filteredOrders=来自订单中的p
其中p.Detail.where(e=>e.StockCode==“STK2”).Count()>0
选择p;
foreach(过滤器中的变量顺序)
{
WriteLine(“帐户{0}”,order.AccountCode);
foreach(订单中的var详细信息。详细信息)
{
WriteLine(“StockCode{0},数量{1}”,detail.StockCode,detail.Quantity);
}
Console.WriteLine();
}
//上述内容将返回以下内容:
//账户客户1
//库存代码STK1,数量1
//库存代码STK2,数量2
//
//客户2
//库存代码STK2,数量1
//库存代码STK4,数量2
//我怎样才能得到以下信息?
//账户客户1
//库存代码STK2,数量2
//
//客户2
//库存代码STK2,数量1
Console.ReadLine();
}
公共静态列表GetOrderHeaders()
{
列表顺序=新列表();
OrderHeader标头=
新订单头{
AccountCode=“CUST1”,
Detail=新列表()};
header.Detail.Add(
新订单详情{StockCode=“STK1”,数量=1});
header.Detail.Add(
新订单详情{StockCode=“STK2”,数量=2});
订单。添加(标题);
标题=
新订单头
{
AccountCode=“CUST2”,
详细信息=新列表()
};
header.Detail.Add(
新订单详情{StockCode=“STK2”,数量=1});
header.Detail.Add(
新订单详情{StockCode=“STK4”,数量=2});
订单。添加(标题);
退货订单;
}
}
公共类OrderHeader
{
公共字符串AccountCode{get;set;}
公共列表详细信息{get;set;}
}
公共类OrderDetail
{
公共字符串StockCode{get;set;}
公共整数数量{get;set;}
}
}
非常感谢您的建议

保罗

尝试以下方法:

var filtered = orders
    .Where(o => o.Detail.Any(d => d.StockCode == "STK2"))
    .Select(o => new { Order = o, Details = o.Detail.Where(d => d.StockCode == "STK2") });
然后可以这样使用:

foreach (var entity in filtered)
{
    Console.WriteLine("Account {0} ", entity.Order.AccountCode);
    foreach (var detail in entity.Details)
    {
        Console.WriteLine("StockCode {0}, Quantity {1}", detail.StockCode, detail.Quantity);
    }
    Console.WriteLine();
}

为什么要痴迷于一个LINQ声明?我应该为这个问题提供更多的背景资料。实际上,我使用的是LINQtoEntity框架,其中我使用动态表达式API生成LINQ语句(作为用户使用UI建立搜索条件的结果)。正因为如此,我更愿意在一条LINQ语句中执行此操作。任何语句中的变量都不必是“o”以外的值,以免更改parent中“o”的含义吗?@ScottA.Lawrence是的,你是对的-我的代码片段不会编译。答案更新,谢谢。