Linq Projection

时间:2009-11-23 09:42:26

标签: .net linq-to-objects

我有一个Customer集合。内部客户我有另一个名为Orders的集合。

订单有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的答案将工作。那么如何只将过滤后的订单添加到订单中?

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

SelectMany用于投影和展平数据结构。有很多重载,但最简单的就是这个。

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

答案 2 :(得分:1)

假设您的类定义与提供的完全一致,但字段(或属性)是公共的,Customer有一个默认的公共构造函数,用空集合初始化其Orders,您可以这样做如果您使用语句lambda(将限制您使用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#集合初始化器不允许你在里面拼接集合。

答案 3 :(得分: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);
}