c# - 如果始终在本地评估 Skip 和 Take,我如何在 EF Core 中运行分页查询?

标签 c# linq entity-framework-core

我有一个 ASP.NET Core Web API,它使用 Entity Framework Core(版本 2.0.2)返回一个名为 PhotoAlbum 的数据模型的分页列表。 .为此,它建立了一个 IQueryable<PhotoAlbum>像这样:

    var query = _context.PhotoAlbums
        .Include(album => album.SpotlightPhotoView)
        .ApplySecurity(user)
        .ApplyFilter(filter)
        .Sort(sortInfo);

在哪里ApplySecurity , ApplyFilterSort是我自己的扩展,它应用两个 Where过滤器和 OrderBy分别过滤。最后代码使用 SkipTake返回匹配数据的特定子集。

我有兴趣在我的日志中看到以下警告:

The LINQ expression '"Take(__p_2)"' could not be translated and will be evaluated locally.

The LINQ expression '"Skip(__p_1)"' could not be translated and will be evaluated locally.

The LINQ expression '"where [album].Featured"' could not be translated and will be evaluated locally.

The LINQ expression '"where (([album].Complete OrElse False) OrElse False)"' could not be translated and will be evaluated locally.

阅读这些警告后,我现在知道 EF Core 中的某些 Linq 方法无法转换为 SQL。这些包括聚合函数,如 SumCount以及SkipTake .

所以我的第一个问题是:如果要实现分页查询,推荐的解决方案是什么?存储过程是option选项吗?

我的第二个问题是:为什么我会在 Where 周围收到警告?子句?

为了详细说明第二个问题,应用 [album].Featured 的代码过滤器看起来像这样......

    query = query.Where(album => album.Featured);

应用[album].Complete的代码过滤器看起来像这样......

    query = query
        .Where(album =>
            album.Complete || filter.IncludeIncomplete
            && album.Published || filter.IncludeUnpublished);

...哪里filter是一个简单的模型,具有一组定义如何过滤的 bool 属性。

下面是根据我的日志执行的实际 SQL(为了便于阅读,从 SELECT 中删除了几列):

SELECT [album].[AlbumID], [album].[AlbumDate], [album.SpotlightPhotoView].[PhotoViewID]
FROM [PhotoAlbum] AS [album]
LEFT JOIN [PhotoView] AS [album.SpotlightPhotoView] ON [album].[SpotlightPhotoViewID] = [album.SpotlightPhotoView].[PhotoViewID]
WHERE ([album].[Complete] = 1) AND ([album].[Featured] = 1)
ORDER BY [album].[AlbumDate] DESC

它似乎应用了 FeaturedComplete尽管有警告,但过滤效果很好。

最佳答案

我怀疑自定义方法及其输入生成的表达式无法转换为 SQL。 where (([album].Complete OrElse False) OrElse False) 绝对不能 - SQL 中没有 OrElseOrElse 是一个 VB.NET 关键字。

[album].Featured 是另一个可疑警告。所有版本都肯定支持按 bool 属性过滤。 Featured 是一个没有正确配置的计算属性吗?

除此之外,还添加了 GROUP BY 和聚合函数 in EF Core 2.1 ,最新的 LTS(长期支持)版本。

Take and Skip 在 EF Core 2.2.6 和 EF Core 3.0 Preview 8 中绝对有效。在 LinqPad 6 中尝试此查询:

Posts.OrderBy(p=>p.PostId).Skip(100).Take(100)

生成此 SQL 查询:

SELECT [p].[PostId], [p].[BlogId], [p].[Content], [p].[Title]
FROM [Posts] AS [p]
ORDER BY [p].[PostId]
OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY

关于c# - 如果始终在本地评估 Skip 和 Take,我如何在 EF Core 中运行分页查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57959475/

相关文章:

c# tooltip backcolor 和 forecolor 不随 using 方法或其他方式改变

c# - LINQ 中 FirstOrDefault() 和 FirstOrDefault<string>() 的区别

c# - LINQ to Entities 在 .NET Core 中导致异常, "Value cannot be null"

c# - 带有 GraphQL 的 EF 核心

asp.net-core-mvc - 迁移到 MVC6/EF7 : PluralizingTableNameConvention

c# - 如何使用 EF 在 SQLite 中启用迁移

c# - 在 Azure Web 应用程序中使用 wkhtmltopdf 时出现 CGI 错误

c# - 如何在 Visual Studio 2008 中获取线程窗口?

c# - 为什么加载区域 Controller 时我的 BaseController.User 值 == null?

c# - 如何将 For 语句转换为 LINQ