【问题标题】:How to take top 10 when lazy loading multiple levels in EF7在 EF7 中延迟加载多个级别时如何获得前 10 名
【发布时间】:2016-07-02 10:37:32
【问题描述】:

举个例子,我有一个Customer > OrdersOrder > Orderlines 的简单域模型。

我想获取所有客户的列表,每个客户都有最近的 10 个订单,包括他们的订单行。

以下 LINQ 不起作用(这并不完全令人惊讶),但如果可能的话,正确的语法应该是什么?

var customers = _context.Customers
            .Include(c => c.Orders)
                 .OrderByDescending(c => c.CreatedDateTime)
                 .Take(10)
                 .ThenInclude(c => c.OrderLines);

生成的 SQL 获取客户的 TOP(10)(而不是订单的 TOP(10))。然后从最终结果中得到 ORDERBY DESC。因此 OrderByDescending 和 Take(10) 应用于客户而不是订单。

更新

以下代码(没有 ThenInclude)

var customers = _context.Customers
                 .Include(c => c.Orders)
                 .OrderByDescending(c => c.Created)
                 .Take(10)

生成以下 SQL..

SELECT [a].[Id], [a].[CreatedDateTime], [a].[CustomerID]
FROM [Order] AS [a]
INNER JOIN (
    SELECT DISTINCT TOP(10) [c].[CreatedDateTime], [c].[Id]
    FROM [Customer] AS [c]
) AS [c] ON [a].[CustomerID] = [c].[Id] ORDER BY [c].[CreatedDateTime] DESC, [c].[Id]

这显然不是我想要的。

【问题讨论】:

  • 定义“不起作用”。它做什么
  • 我应该已经发布了生成的 SQL。我会回到它,看看我是否可以添加到问题中。我添加了行为摘要。

标签: c# sql entity-framework linq entity-framework-core


【解决方案1】:

我显然无法对此进行测试,但您不需要使用 Count 吗?

var customers = _context.Customers
            .Include(c => c.Orders)
                 .OrderByDescending(c => c.CreatedDateTime)
                 .ThenInclude(c => c.OrderLines).Take(10);

【讨论】:

  • 不确定我是否理解那个克里斯。让我编辑我的帖子,使其更具体一点。
  • 会试一试的。
【解决方案2】:

试试这个

 var customers = from n in _context.Customers
                    select
                        new
                        {
                            n,
                            Orders = _context.Orders.Where(l => l.CustomeId == 
                             n.CustomeId).OrderByDescending(l => l.Date).Take(10)
                        };

【讨论】:

  • 谢谢玛丽,是的,这确实有效,但返回匿名类对象而不是客户和 x2 命中数据库。我可以在 SQL 中为此创建一个查询,我只想在代码中执行此操作。我会进一步调查。可能我正在寻找的东西是不可能的。
【解决方案3】:

你想将 ordering 和 TOP 应用到 Orders,所以调用 Orders 上的方法而不是 Customers:

var customers = _context.Customers
        .Include(c => c.Orders
             .OrderByDescending(c => c.CreatedDateTime)
             .Take(10)
             .Include(c => c.OrderLines));

【讨论】:

  • 试过这个 Rik 并抛出:“无法将类型为 'Remotion.Linq.Clauses.Expressions.SubQueryExpression' 的对象转换为类型 'System.Linq.Expressions.MemberExpression'。”
  • 是的,我刚刚发现子查询(选择除外)在包含中不起作用。我正在研究一种新方法。
  • 我想我可以单独添加范围,但这需要两个数据库命中我想...
猜你喜欢
  • 1970-01-01
  • 2012-07-25
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多