2012-01-17 8 views
8

親エンティティにクエリを行い、子コレクションの内容をフィルタリングできるようにしたいと考えています。LINQ - 子コレクションのフィルタリング

たとえば、私はOrderHeadersのコレクションを持っています。私はすべてのOrderHeadersを返すためにLINQを使用してこのコレクションを照会したいが、私は関連するOrderDetail行のいくつかが含まれることを望む。

私はすべてのことを1つの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; } 
    } 

} 

事前にお礼を申し上げます。

ポール

+1

なぜ強迫観念単一LINQ文で? –

+0

私はこの質問の背景をもっと与えるべきです。実際には、LINQをEntity Frameworkに使用していますが、Dynamic Expression APIを使用してLINQステートメントを生成しています(ユーザーがUIで検索条件を作成した結果として)。このため、私は1つのLINQステートメントでそれを行うことをお勧めします。 – P2l

答えて

16

は、以下のことを試してみてください。そのようにように使用可能である

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

親の "o"の意味を変更しないように、 "Any"の変数は "o"以外のものでなくてはなりませんか? –

+0

@ ScottA.Lawrenceはい、そうです。私のコードスニペットはコンパイルされません。回答が更新されました。 –

+0

@ rich-okellyようこそ。喜んでお手伝いします。 –

関連する問題