繁体   English   中英

在数据库的单次往返中执行两个查询

[英]Performing two queries in a single round trip to the database

我有以下代码来执行全文搜索。 它创建一个查询,获取该查询返回的总行数,然后仅检索当前页面的实际行数。

// Create IQueryable
var query = from a in ArticleServerContext.Set<Article>()
            where a.Approved
            orderby a.UtcDate descending
            select a;

// Get total rows (needed for pagination logic)
int totalRows = query.Count()

// Get rows for current page
query = query.Skip((CurrentPage - 1) * RowsPerPage).Take(RowsPerPage);

这工作正常,但它需要两次往返数据库。 为了优化代码,有没有办法重新编写这个查询,所以它只有一次往返数据库?

是的,您可以在对数据库的唯一一个查询的帮助下执行这两个操作:

// Create IQueryable
var query = from a in ArticleServerContext.Set<Article>()
            where a.Approved
            orderby a.UtcDate descending
            select new { a, Total = ArticleServerContext.Set<Article>().Where(x => x.Approved).Count() };

//Get raw rows for current page with Total(Count) field
var result = query.Skip((CurrentPage - 1) * RowsPerPage).Take(RowsPerPage).ToList();

//this data you actually will use with your logic 
var actualData = result.Select(x => x.a).ToList();

// Get total rows (needed for pagination logic)
int totalRows = result.First().Total;

如果您使用MSSQL query将看起来那样:

SELECT 
    [Extent1].[ID] AS [ID], 
    [Extent1].[UtcDate] AS [UtcDate], 
    [Extent1].[Approved] AS [Approved],     
    [GroupBy1].[A1] AS [C1]
    FROM  [dbo].[Articles] AS [Extent1]
    CROSS JOIN  (SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[Articles] AS [Extent2]
        WHERE [Extent2].[Approved] ) AS [GroupBy1]
    WHERE [Extent1].[Approved]
    ORDER BY [Extent1].[UtcDate] DESC

我不确定它是否足够值,但在以下限制条件下它是可行的:

(1) CurrentPageRowsPerPage不受totalRows值的影响。
(2)在应用寻呼参数后实现查询。

诀窍是使用由EF支持的常量值group by 代码如下所示:

var query = 
    from a in ArticleServerContext.Set<Article>()
    where a.Approved
    // NOTE: order by goes below
    group a by 1 into allRows
    select new
    {
        TotalRows = allRows.Count(),
        PageRows = allRows
            .OrderByDescending(a => a.UtcDate)
            .Skip((CurrentPage - 1) * RowsPerPage).Take(RowsPerPage)
    };

var result = query.FirstOrDefault();
var totalRows = result != null ? result.TotalRows : 0;
var pageRows = result != null ? result.PageRows : Enumerable.Empty<Article>();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM