2009-11-23 25 views
1

我有一個客戶收藏。內部客戶我有另一個名爲訂單的集合。Linq Projection

訂單具有Name,OrderDate,PurchaseID。

如何寫一個Linq查詢給我一個新的客戶集合,其中只包含OrderDate> QueryDate的訂單?

爲了協助這裏的討論,我們提供了相關的代碼集。我只需要了解這個概念。

class Customer 
{ 
    List<Order> Orders; 
} 

class Order 
{ 
    string Name; 
    Date OrderDate; 
    int PurchaseID; 
} 

List<Customer> customers; 

我遇到了一個我不知道的新路障。訂單是隻讀屬性。它需要通過customers.Orders.Add(...)訪問,如果不是SharePoint答案將工作。那麼如何只將已過濾的訂單添加到訂單中?

回答

1

假設你的類定義是完全按照規定,除了字段(或屬性)是公開的,而且Customer有初始化其Orders一個空集合的默認公共構造,如果你使用的語句拉姆達(這將限制你L2O,並阻止你使用L2S或EF),你可以做到這一點:

var result = customers.Select(c => 
{ 
    var cf = new Customer(); 
    cf.Orders.AddRange(c.Orders.Where(o.OrderDate > QueryDate)); 
    return cf; 
}); 

不幸的是,有沒有辦法用一個表達式lambda來做到這一點,因爲C#集合初始化器不允許你在裏面拼接集合。

+0

將是偉大的,如果我們可以做到這一點,這將完美的工作。謝謝 – firefly 2009-11-24 15:36:07

+0

我已經要求一個C#特性來在集合初始化上下文中自動擴展IEnumerable(這樣你就可以編寫例如'new Customer {Orders = {c.Orders.Where(o.OrderDate> QueryDate)}}' - 參見https ://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID = 377830,如果您希望在未來的C#版本中查看此功能(或針對同一事物的不同語法),請爲此投票。 – 2009-11-24 16:41:33

1

SelectMany用於投影和展平數據結構。有很多重載,但最簡單的是這個。

customers.SelectMany(c => c.Orders).Where(o => o.OrderDate > queryDate); 
+0

如果我沒有弄錯,這給我一個訂單集合,我想要一組訂單過濾掉的客戶集合。 – firefly 2009-11-24 00:13:41

+0

你是對的,對不起,我一定誤解了這個問題。我以爲你想收集訂單。 – 2009-11-24 08:25:28

2

customers .Select(c => new Customer { Orders = c.Orders.Where(o => o.OrderDate > DateTime.Now)} );

+0

這將返回客戶的集合,其中每個客戶僅包含相關訂單。該請求是針對訂單的平面清單。 – 2009-11-23 11:31:20

+0

這實際上更接近我所尋找的。雖然我遇到了障礙,因爲訂單是隻獲取屬性。請參閱我編輯的問題 – firefly 2009-11-24 00:12:22

0

我不認爲你可以在Linq的做到這一點。你將不得不做這樣的事情:

var filtered = new List<Customer>(); 
foreach (var c in customers) 
{ 
    var customer = new Customer(); 
    customer.Orders.AddRange(c.Orders.Where(o => o.OrderDate > queryDate)); 
    filtered.Add(customer); 
} 
相關問題