Linq Projection
I have an Customer collection. Inside Customer I have another collection called Orders.
Order have Name, OrderDate, PurchaseID.
How do write a Linq query to give me a new customer collection that only contain Orders that have OrderDate > QueryDate?
To aid with the discussion here is the relevant set of the code. I just need to understand the concept.
class Customer
{
List<Order> Orders;
}
class Order
{
string Name;
Date OrderDate;
int PurchaseID;
}
List<Customer> customers;
I am running into a new roadblock that I wasn't aware of. Orders is a readonly property. It need to be access via customers.Orders.Add(...) if not SharePoint answer would开发者_开发知识库 work. So how do add only the filtered Orders into Orders?
customers
.Select(c =>
new Customer { Orders = c.Orders.Where(o => o.OrderDate > DateTime.Now)}
);
Assuming your class definitions are exactly as provided, except that fields (or properties) are public, and Customer
has a default public constructor that initializes its Orders
with an empty collection, you can do it if you use a statement lambda (which will restrict you to L2O, and prevent you from using L2S or EF):
var result = customers.Select(c =>
{
var cf = new Customer();
cf.Orders.AddRange(c.Orders.Where(o.OrderDate > QueryDate));
return cf;
});
Unfortunately, there's no way to do it with an expression lambda, because C# collection initializers don't allow you to splice collections inside.
SelectMany is used for projections and flattening data structures. There are a lot of overloads, but the simplest one is this.
customers.SelectMany(c => c.Orders).Where(o => o.OrderDate > queryDate);
I don't think you can do it in Linq. You will have to do something like:
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);
}
精彩评论