【问题标题】:Use Linq to get the last order placed yesterday for each customer使用 Linq 获取每个客户昨天下的最后一个订单
【发布时间】:2015-10-25 00:35:04
【问题描述】:

我有以下两个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;}
}

我之前发布了一个关于使用 Linq 处理列表的类似问题。我还在学习 Linq,这些问题让我有些困惑。我希望有人可以提供帮助。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    试试这个:

    var results = customers
        .Select(c =>
            orders
                .Where(o => o.CustomerId == c.Id)
                .Where(o => o.Date.Date == DateTime.Now.AddDays(-1).Date)
                .OrderByDescending(o => o.Date)
                .Select(o => new CustomerOrders()
                {
                    Product = o.Product,
                    Date = o.Date,
                    CustomerId = c.Id,
                    LastName = c.LastName,
                    FirstName = c.FirstName,
                    OrderId = o.Id
                })
                .First())
        .ToList();
    

    这里是另一个版本,用于处理客户没有符合条件的相应订单的情况:

    var results = customers
        .Select(c =>
            orders
                .Where(o => o.CustomerId == c.Id)
                .Where(o => o.Date.Date == DateTime.Now.AddDays(-1).Date)
                .OrderByDescending(o => o.Date)
                .DefaultIfEmpty()
                .Select(o => new CustomerOrders()
                {
                    Product = o == null ? default(string) : o.Product,
                    Date = o == null ? default(DateTime) : o.Date,
                    CustomerId = c.Id,
                    LastName = c.LastName,
                    FirstName = c.FirstName,
                    OrderId = o == null ? default(Guid) : o.Id
                })
                .First())
        .ToList();
    

    【讨论】:

    • 我收到一个 InvalidOperationException 并突出显示内部订单...First()。
    • 可能有些客户没有对应的订单?你想怎么处理这种情况?
    • 这就是问题所在。其中一位客户昨天没有订单。为了处理这种情况,我只是调整了数据。这就是这个示例所需要的全部内容。
    • 只是出于好奇,我该如何处理这种情况(昨天没有数据)并且对于昨天没有访问的任何用户默认为空记录?
    【解决方案2】:

    大概是这样的..

    var res = from c in customers
              join o in orders on c.Id equals o.CustomerId
              where o.Id == (orders.Where(x=>x.CustomerId == o.CustomerId).OrderByDescending(x=>x.Id)).First().Id
              && DateTime.Compare(o.Date, DateTime.Now.AddDays(-1)) > 0
              select new CustomerOrders {
                  CustomerId = c.Id, FirstName = c.FirstName, LastName = c.LastName,
                  OrderId = o.Id, Date = o.Date, Product = o.Product 
              };
    

    附:我没有编译就写了,你可能会遇到一些错误,但我想你明白了。

    【讨论】:

    • 这不会编译,但看起来像我正在尝试做的事情。我在 where 子句中遇到问题:orders.where(x=>x... 它表示存在无效的表达式术语 'where'。
    • 你能具体说明这个实现有什么问题吗?
    • 此条目的问题与以下行有关: where o.Id == (orders.where(x=>x.CustomerId == o.CustomerId).OrderByDescending(x=> x.Id)).First().Id 内部orders.where 显示错误编译'where' 是一个无效的epression。因此当前上下文中不存在 First() 以及 select
    • 你知道'Orders'是List,里面有数据吗?
    • 列表中肯定有数据。错误不在运行时,而是在设计时,不会编译。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2019-12-27
    • 2010-12-08
    • 2022-12-06
    • 1970-01-01
    • 2021-11-12
    相关资源
    最近更新 更多