【问题标题】:EF query using extension method inside extension method在扩展方法中使用扩展方法的 EF 查询
【发布时间】:2015-03-12 08:16:48
【问题描述】:

我有表格请求,有批准:

public class Request {
    public virtual List<Approval> Approvals { get; set; } 
}

请求来自数据库

public DbSet<Request> Request { get; set; }

我有扩展方法:

public static IQueryable<Request> HaveApprovals(this IQueryable<Request> requests) {
    return requests.Where(r => r.ActiveApprovals().Count() > 0).ToList();
}

还有另一种扩展方法:

public static IEnumerable<Approval> ActiveApprovals(this Request request) {
     return request.Approvals.Where(a => !a.Deleted);
}

但出现错误:

LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable`1[Domain.Approval] ActiveApprovals(Domain.Request)' method, and this method cannot be translated into a store expression.

由于某种原因,一种扩展方法能够被转换为 LINQ,但是当在另一种方法中使用扩展方法时,它无法转换。有什么建议吗?

【问题讨论】:

  • 你也应该从第二个返回 IQueryable
  • 如果可以的话我会,但request.Approvals 是List,使用Where 返回IEnumerable。

标签: c# linq entity-framework linq-to-entities extension-methods


【解决方案1】:

尝试以这种方式重写您的 HaveApprovals 扩展:

public static IQueryable<Request> HaveApprovals(this IQueryable<Request> requests) {
    return requests.Where(r => r.Approvals.Any(a => !a.Deleted)).ToList();
}

发生错误是因为 EF 尝试在服务器端(SQL 服务器)的查询中执行任何操作。所以 SQL 对你的扩展方法以及如何执行它一无所知。

更新#1:

以下查询

var query = this.DataContext.Products.Where(x => x.Sales.Any(s => s.SectorId == 1));

将生成以下 SQL 查询

SELECT [t0].[Id], [t0].[Name], [t0].[Description]
FROM [dbo].[Products] AS [t0]
WHERE EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Sales] AS [t1]
    WHERE ([t1].[SectorId] = @p0) AND ([t1].[ProductId] = [t0].[Id])
    )
}

它不会提取所有记录,因此不会降低性能。

【讨论】:

  • 我希望它在查询中执行,否则它会从数据库中加载我的 100k 项,而且速度非常慢。它应该能够将扩展方法内容转换为 LINQ,就像它只使用单个扩展方法而不是嵌套时一样。
  • 我已经用一些证据更新了我的答案。查询不会提取您的 100k 项(请参阅类似查询和生成的 SQL 查询)。也没有办法将自定义扩展方法翻译成 SQL。
  • 查看这个主题,看看如果使用 IEnumerable,它将执行整个查询,并且过滤将在内存中完成。 stackoverflow.com/questions/2876616/…
  • 我建议在这里删除ToList,这样您就不会从范围内执行查询。将其留给包含上下文来决定何时执行,这样您就可以组合其中的几个扩展。
【解决方案2】:

返回 Iqueryable 或 Ienumerable 而不是列表。查询将由 sql 处理,因此无法理解返回的列表

【讨论】:

    猜你喜欢
    • 2011-10-02
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 2012-10-14
    • 1970-01-01
    • 2022-11-09
    相关资源
    最近更新 更多