【问题标题】:Using Linq to get date of last order for all customers使用 Linq 获取所有客户的最后订单日期
【发布时间】:2015-10-24 08:56:08
【问题描述】:

我有以下两个POCO

public class Customers
{
    public Guid Id { get; set; }
    public string FirstName{ get; set; }
    public string LastName{ get; set; }
}

public class Orders
{
    public Guid Id { get; set; }
    public Guid CustomerId { get; set; }
    public string Product { get; set; }
    public DateTime Date { get; set; }
}

假设我的数据服务返回 List 和 List,我将如何使用 Linq 获取每个客户的最后一个订单的日期?

我想返回 Customer.Id、Customer.FirstName、Customer.LastName、Order.Id、Order.Date 和 Order.Product(作为控制器操作中的 Json),所以我还需要创建一个新的 POCO 来持有结果?类似于以下内容:

public class CustomerOrders
{
    public Guid CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Guid OrderId { get; set; }
    public DateTime Date { get; set; }
    public string Product { get; set; }
}

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    您可能希望像这样使用GROUP BYJOIN

    var customerOrders =
        (from c in customers
         join o in (from o1 in orders
                    group o1 by o1.CustomerId into og
                    select new { CustomerId = og.Key, Latest = og.Max(d => d.Date) })
         on c.Id equals o.CustomerId
         join o2 in orders
         on new {CustmerId = o.CustomerId, Date = o.Latest } 
         equals new { CustmerId = o2.CustomerId, Date = o2.Date }
    
         select new CustomerOrders
         {
             CustomerId = c.Id,
             FirstName = c.FirstName,
             LastName = c.LastName,
             OrderId = o2.Id,
             Date = o.Latest,
             Product = o2.Product
         });
    

    如果您想要没有任何订单的客户的结果,请使用LEFT OUTER JOIN 和使用DefaultIfEmpty,如下所示:

    var customerOrders =
        (from c in customers
         join o in (from o1 in orders
                    group o1 by o1.CustomerId into og
                    select new { CustomerId = og.Key, Latest = og.Max(d => d.Date) })
         on c.Id equals o.CustomerId into co
         from o in co.DefaultIfEmpty()  // LEFT OUTER JOIN 1
         join o2 in orders
         on new { CustmerId = (o == null)? Guid.Empty : o.CustomerId, Date = (o == null)? DateTime.MinValue : o.Latest }
         equals new { CustmerId = o2.CustomerId, Date = o2.Date } into oo
         from o2 in oo.DefaultIfEmpty()  // LEFT OUTER JOIN 2
    
         select new CustomerOrders
         {
             CustomerId = c.Id,
             FirstName = c.FirstName,
             LastName = c.LastName,
             OrderId = (o2 == null)? Guid.Empty : o2.Id,
             Date = (o == null)? DateTime.MinValue : o.Latest,
             Product = (o == null)? null : o2.Product
         });
    

    请注意LEFT OUTER JOIN 可能会加入空值,因此您必须在 linq 查询中添加空检查。

    【讨论】:

    • 您提到了 LEFT OUTER JOIN 并使用 DefaultIfEmpty。您能否指出具体的加入以及我将在哪里使用 DefaultIfEmpty?谢谢
    • 嗨@user3583 我已经更新了LEFT OUTER JOIN 案例的答案。
    猜你喜欢
    • 2023-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    相关资源
    最近更新 更多