2012-01-17 22 views
8

Ebeveyn varlıkları sorgulayabilmek ve bir çocuk koleksiyonu içindekileri filtrelemek istiyorum.LINQ - filtre çocuk koleksiyonu

Örneğin, bir OrderHeaders koleksiyonum var. Tüm OrderHeaders döndürmek için LINQ kullanarak bu koleksiyonu sorgulamak istiyorum, ancak ben sadece ilgili OrderDetail satırlarının dahil edilmesini istiyorum.

Tüm bunları tek bir LINQ ifadesinde yapabileceğim bir çözüm arıyorum.

Aşağıdaki konsol uygulaması bunu gösterir.

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

} 

Önerileriniz için şimdiden çok teşekkürler.

Paul

+1

Neden tek LINQ deyimi takıntısı? –

+0

Bu soruya daha fazla arka plan vermeliyim. Aslına bakılırsa, Dinamik Ekspresyon API'sini kullanarak LINQ ifadesini oluşturduğum Entity Framework'e LINQ kullanıyorum (kullanıcı bir UI ile bir arama ölçütü oluşturmanın sonucu olarak). Bundan dolayı bunu bir LINQ ifadesinde yapmayı tercih ederim. – P2l

cevap

16

deneyin:

şöyle sonra deresindeki
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

Ebeveynteki "o" ifadesini değiştirmemek için, Vardaki değişken "o" dan başka bir şey değil midir? –

+0

@ ScottA.Lawrence Evet, haklısınız - kod snippet'im derlemedi. Cevap güncellendi, teşekkürler. –

+0

@ rich-okelly hoşgeldiniz - yardımcı olmaktan memnuniyet duyarız. –