繁体   English   中英

LINQ查询 - 仅从子集合中获取Order和MAX Date

[英]LINQ Query - Only get Order and MAX Date from Child Collection

我正在尝试获取一个列表,该列表在父和子(1- *)实体集合模型的标签中显示2个值。

我有3个实体:

  1. [ 客户 ]:CustomerId,姓名,地址,......
  2. [ 订单 ]:OrderId,OrderDate,EmployeeId,Total,...
  3. [ OrderStatus ]:OrderStatusId,StatusLevel,StatusDate,...

一个客户可以有许多订单 ,这反过来又一个订单可以具有许多OrderStatus,即[ 客户 ] 1 - * [ 订购 ] 1 - * [OrderStatus]

给定CustomerId,我想获得该订单的所有订单(只是OrderId)和LATEST(MAX?)OrderStatus.StatusDate。

我尝试了几次尝试,但似乎可以得到我想要的结果。

private IQueryable<Customer> GetOrderData(string customerId)
{
     var ordersWithLatestStatusDate = Context.Customers

     // Note: I am not sure if I should add the .Expand() extension methods here for the other two entity collections since I want these queries to be as performant as possible and since I am projecting below (only need to display 2 fields for each record in the IQueryable<T>, but thinking I should now after some contemplation.

     .Where(x => x.CustomerId == SelectedCustomer.CustomerId)
     .Select(x => new Custom 
     {
         CustomerId = x.CustomerId,
         ...
         // I would like to project my Child and GrandChild Collections, i.e. Orders and OrderStatuses here but don't know how to do that. I learned that by projecting, one does not need to "Include/Expand" these extension methods.  
     });
     return ordersWithLatestStatusDate ;
}

----更新1 ----

在User: lazyberezovsky的出色解决方案之后,我尝试了以下方法:

var query = Context.Customers
            .Where(c => c.CustomerId == SelectedCustomer.CustomerId)
            .Select(o => new Customer 
            { 
                Name = c.Name, 
                LatestOrderDate = o.OrderStatus.Max(s => s.StatusDate) 
            });

在我最初的帖子中,我没有正确地粘贴所有内容,因为它主要来自内存,并且当时没有确切的代码供参考。 我的方法是一个强类型的IQueryabled,我需要它来返回类型为T的项的集合,因为我必须通过一个具有IQueryable查询作为其参数之一的刚性API中的约束。 我知道我可以通过使用扩展方法.Expand()和/或.Select()来添加其他实体/属性。 人们会注意到我上面的最新UPDATED查询在.Select()中添加了一个“新客户”,它曾经是匿名的。 我很肯定这就是为什么查询失败b / c它无法变成有效的Uri,因为LatestOrderDate不是服务器级别的Customer属性。 仅供参考,在看到下面的第一个答案后,我将该属性添加到我的客户端Customer类中,并使用简单的{get; 组; }。 所以,鉴于此,我可以以某种方式仍然拥有一个Customer集合,只从两个不同的实体中带回那两个字段吗? 下面的解决方案看起来非常有前途和巧妙!

----结束更新1 ----

仅供参考,我使用的技术是OData(WCF),Silverlight,C#。

任何提示/链接将不胜感激。

这将为您提供{ OrderId, LatestDate }对象的列表

var query = Context.Customers
                   .Where(c => c.CustomerId == SelectedCustomer.CustomerId)
                   .SelectMany(c => c.Orders)
                   .Select(o => new { 
                              OrderId = o.OrderId, 
                              LatestDate = o.Statuses.Max(s => s.StatusDate) });

               .

UPDATE构造内存中的对象

var query = Context.Customers
                   .Where(c => c.CustomerId == SelectedCustomer.CustomerId)
                   .SelectMany(c => c.Orders)
                   .AsEnumerable() // goes in-memory
                   .Select(o => new { 
                              OrderId = o.OrderId, 
                              LatestDate = o.Statuses.Max(s => s.StatusDate) });

分组也可以在这里提供帮助。

如果我正确读取了这个,你想要一个Customer实体,然后从它的Orders属性计算一个值。 目前OData不支持此功能。 OData不支持查询中的计算值。 所以投影中没有表达式,没有聚合等等。

不幸的是,即使有两个查询,这也是不可能的,因为OData不支持任何表达MAX功能的方式。

如果您可以控制服务,则可以编写服务器端功能/服务操作来执行此类查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM