c# - Entity Framework /Linq to SQL : Skip & Take

标签 c# .net linq-to-sql sql-server-2008 entity-framework-4

只是好奇 Skip & Take 应该如何工作。我得到了我想在客户端看到的结果,但是当我连接 AnjLab SQL Profiler 并查看正在执行的 SQL 时,它看起来好像正在查询并将整组行返回到客户。

它真的会返回所有行,然后在客户端使用 LINQ 进行排序和缩小范围吗?

我尝试过使用 Entity Framework 和 Linq to SQL 来实现;两者似乎具有相同的行为。

不确定它有什么不同,但我在 VWD 2010 中使用 C#。

有什么见解吗?

public IEnumerable<Store> ListStores(Func<Store, string> sort, bool desc, int page, int pageSize, out int totalRecords)
{
    var context = new TectonicEntities();
    totalRecords = context.Stores.Count();
    int skipRows = (page - 1) * pageSize;
    if (desc)
        return context.Stores.OrderByDescending(sort).Skip(skipRows).Take(pageSize).ToList();
    return context.Stores.OrderBy(sort).Skip(skipRows).Take(pageSize).ToList();
}

生成的 SQL(注意:我排除了 Count 查询):

SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[Name] AS [Name], 
[Extent1].[LegalName] AS [LegalName], 
[Extent1].[YearEstablished] AS [YearEstablished], 
[Extent1].[DiskPath] AS [DiskPath], 
[Extent1].[URL] AS [URL], 
[Extent1].[SecureURL] AS [SecureURL], 
[Extent1].[UseSSL] AS [UseSSL]
FROM [dbo].[tec_Stores] AS [Extent1]

经过进一步的研究,我发现下面的方法符合我的预期:

public IEnumerable<Store> ListStores(Func<Store, string> sort, bool desc, int page, int pageSize, out int totalRecords)
{
    var context = new TectonicEntities();
    totalRecords = context.Stores.Count();
    int skipRows = (page - 1) * pageSize;           
    var qry = from s in context.Stores orderby s.Name ascending select s;
    return qry.Skip(skipRows).Take(pageSize);           
}

生成的 SQL:

SELECT TOP (3) 
[Extent1].[ID] AS [ID], 
[Extent1].[Name] AS [Name], 
[Extent1].[LegalName] AS [LegalName], 
[Extent1].[YearEstablished] AS [YearEstablished], 
[Extent1].[DiskPath] AS [DiskPath], 
[Extent1].[URL] AS [URL], 
[Extent1].[SecureURL] AS [SecureURL], 
[Extent1].[UseSSL] AS [UseSSL]
FROM ( SELECT [Extent1].[ID] AS [ID], [Extent1].[Name] AS [Name], [Extent1].[LegalName] AS [LegalName], [Extent1].[YearEstablished] AS [YearEstablished], [Extent1].[DiskPath] AS [DiskPath], [Extent1].[URL] AS [URL], [Extent1].[SecureURL] AS [SecureURL], [Extent1].[UseSSL] AS [UseSSL], row_number() OVER (ORDER BY [Extent1].[Name] ASC) AS [row_number]
    FROM [dbo].[tec_Stores] AS [Extent1]
)  AS [Extent1]
WHERE [Extent1].[row_number] > 3
ORDER BY [Extent1].[Name] ASC

我真的很喜欢第一个选项的工作方式;传入 lambda 表达式进行排序。有什么方法可以在 LINQ to SQL orderby 语法中完成同样的事情吗?我尝试使用 qry.OrderBy(sort).Skip(skipRows).Take(pageSize),但最终得到的结果与我的第一段代码相同。让我相信我的问题在某种程度上与 OrderBy 有关。

====================================

问题解决了

必须将传入的 lambda 函数包装在表达式中:

Expression<Func<Store,string>> sort

最佳答案

以下工作并实现了我一直在寻找的简单性:

public IEnumerable<Store> ListStores(Expression<Func<Store, string>> sort, bool desc, int page, int pageSize, out int totalRecords)
{
    List<Store> stores = new List<Store>();
    using (var context = new TectonicEntities())
    {
        totalRecords = context.Stores.Count();
        int skipRows = (page - 1) * pageSize;
        if (desc)
            stores = context.Stores.OrderByDescending(sort).Skip(skipRows).Take(pageSize).ToList();
        else
            stores = context.Stores.OrderBy(sort).Skip(skipRows).Take(pageSize).ToList();
    }
    return stores;
}

为我修复它的主要事情是将 Func 排序参数更改为:

Expression<Func<Store, string>> sort

关于c# - Entity Framework /Linq to SQL : Skip & Take,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3870091/

相关文章:

c# - async 如何处理封闭的 UI?

c# - SOLID 原则真的很扎实吗?

c# - 同时具有 CASE 语句和 SUM 函数的 LINQ 查询

c# - 我什么时候应该使用 "var"而不是 "object"?

c# - 如何制作字符串的下一步。 C#

c# - 如何制作 if 语句来检查多个列表框是否为空?

c# - 从 CF 的工具箱中隐藏 UserControl

asp.net - 遍历结果集.Net

c# - 重构返回匹配值的 linq-to-sql 方法

ASP.NET 4 SQL 方法?