【问题标题】:Select The Record With the Lowest Payment for Each Customer using EntityFramework Core使用 EntityFramework Core 为每个客户选择支付最低的记录
【发布时间】:2018-09-25 04:26:59
【问题描述】:

我有一个应用程序可以将客户与库存中的车辆进行匹配。有 3 个主表:Customer、Match 和 Inventory。匹配记录包含特定客户和库存记录的估计每月付款。一个客户可以与 Inventory 中的多辆车匹配。

匹配记录包含一个 CustomerId 和一个 InventoryId 以及一个 MonthlyPayment 字段和一些其他杂项字段。

Customer 和 Match 之间存在一对多的关系。 Inventory 和 Match 之间存在一对多的关系。

对于每个客户,我想选择客户记录、每月付款最低的匹配记录以及该匹配的库存记录。

最好的方法是什么?可以通过单个查询完成吗?

我试过这段代码,但实体框架无法评估它,它会在本地执行它,这会影响性能。

var bestMatches = _matchRepository.GetAll(customerMatchSummaryRequest)
                              .Where(match =>
                                    (_matchRepository.GetAll(customerMatchSummaryRequest)
                                    .GroupBy(m => new { m.Bpid, m.BuyerId, m.CurrentVehicleId })
                                    .Select(g => new
                                    {
                                        g.Key.Bpid,
                                        g.Key.BuyerId,
                                        g.Key.CurrentVehicleId,
                                        LowestMonthlyPayment = g.Min(m => m.MonthlyPayment)
                                    })
                                    .Where(m => m.Bpid == match.Bpid
                                        && m.BuyerId == match.BuyerId
                                        && m.CurrentVehicleId == match.CurrentVehicleId
                                        && m.LowestMonthlyPayment == match.MonthlyPayment)
                                  ).Any())
                              .Include(m => m.Buyer)
                              .Include(m => m.Inventory);

我在单步调试调试器时收到以下输出:

Microsoft.EntityFrameworkCore.Query:Warning: The LINQ expression 'GroupBy(new <>f__AnonymousType2`3(Bpid = [<generated>_2].Bpid, BuyerId = [<generated>_2].BuyerId, CurrentVehicleId = [<generated>_2].CurrentVehicleId), [<generated>_2])' could not be translated and will be evaluated locally.
Microsoft.EntityFrameworkCore.Query:Warning: The LINQ expression 'GroupBy(new <>f__AnonymousType2`3(Bpid = [<generated>_2].Bpid, BuyerId = [<generated>_2].BuyerId, CurrentVehicleId = [<generated>_2].CurrentVehicleId), [<generated>_2])' could not be translated and will be evaluated locally.

【问题讨论】:

    标签: c# entity-framework-core


    【解决方案1】:

    假设你的模型是这样的

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Match> Matches { get; set; }
    }
    
    public class Inventory
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Match> Matches { get; set; }
    }
    
    public class Match
    {
        public int CustomerId { get; set; }
        public Customer Custmer { get; set; }
        public int InventoryId { get; set; }
        public Inventory Inventory { get; set; }
        public decimal MonthlyPayment { get; set; }
    }
    

    有问题的查询可能是这样的:

    var query =
        from customer in db.Set<Customer>()
        from match in customer.Matches
        where !customer.Matches.Any(m => m.MonthlyPayment > match.MonthlyPayment)
        select new
        {
            Customer = customer,
            Match = match,
            Inventory = match.Inventory
        };
    

    请注意,如果它包含多个付款最低的库存记录,它可能会为客户返回多个匹配项。如果数据允许,并且您希望每个客户恰好获得 0 或 1 个结果,请更改

    m.MonthlyPayment > match.MonthlyPayment
    

    条件

    m.MonthlyPayment > match.MonthlyPayment ||
    (m.MonthlyPayment == match.MonthlyPayment && m.InventoryId < match.InventoryId)
    

    附:上面的 LINQ 查询是当前转换为单个 SQL 查询的唯一方法。不幸的是,更自然的方式像

        from customer in db.Set<Customer>()
        let match = customer.Matches.OrderBy(m => m.MonthlyPayment).FirstOrDefault()
        ...
    

        from customer in db.Set<Customer>()
        from match in customer.Matches.OrderBy(m => m.MonthlyPayment).Take(1)
        ...
    

    转到client evaluation

    【讨论】:

    • 我会试一试的。谢谢
    猜你喜欢
    • 2012-08-25
    • 2012-06-04
    • 2016-03-11
    • 1970-01-01
    • 2014-11-13
    • 2014-07-31
    • 2021-11-12
    • 2021-02-25
    • 2011-09-13
    相关资源
    最近更新 更多