Retrieving 10 records at a time only using LINQ
我目前正在研究Kendoui网格的服务器端分页和数据调用。我可以让网格执行服务器端事务,但我注意到,即使选择全部或前10个,对SQL数据库的读取也是相同的。
返回所有记录时,SQL事件探查器的读取值为104。当只返回10条记录时,它的SQL事件探查器读取值为104。
用于返回数据的函数
1 2 3 4 5 6 7 | public List<Employee> GetEmployees(int take, int skip) { return GetRepo<Employee>().All(null).where(p => p.IsDeleted == false).OrderBy(p => p.EmployeeNumber).Skip(10).Take(10).ToList(); } |
当Linq执行10记录调用时,我使用了内置的.skip()和.take()函数。这个方法需要一个.order by()函数才能工作,我在表中有order by the id列。
当使用.skip()和.take()函数时,它会在用于一次调用所有记录的同一查询的外部包装一个前10个。请查看从SQL事件探查器中提取的SQL,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | SELECT TOP (10) * FROM ( SELECT *, row_number() OVER (ORDER BY [Project1].[EmployeeNumber] ASC) AS [row_number] FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent2].[EmployeeNumber] AS [EmployeeNumber], [Extent2].[WeeklyHours] AS [WeeklyHours], '0X0X' AS [C1] FROM [dbo].[Person] AS [Extent1] INNER JOIN [dbo].[Employee] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id] WHERE 0 = [Extent2].[IsDeleted] ) AS [Project1] ) AS [Project1] WHERE [Project1].[row_number] > 0 ORDER BY [Project1].[EmployeeNumber] ASC |
该项目是一个ASP.NET MVC项目,使用的是框架4.5。
有没有一种方法可以在不扫描整个表的情况下返回10条记录?因为员工和人员表在任何时候都将增长到超过100万条活动记录。
如果这是错误的分类,我很抱歉。
任何帮助都将不胜感激。
谢谢。
不要使用list,而是尝试使用iqueryable或IEnumerable。下面是一个例子:
1 2 3 4 | public IQueryable<Employee> GetEmployees(int take, int skip) { return GetRepo<Employee>().All(null).where(p => p.IsDeleted == false).OrderBy(p => p.EmployeeNumber).Skip(10).Take(10); } |
注:
IQueryable is intended to allow a query provider (for example, an ORM like LINQ to SQL or the Entity Framework) to use the
expressions contained in a query to translate the request into another
format. In other words, LINQ-to-SQL looks at the properties on the
entities that you're using along with the comparisons you're making
and actually creates a SQL statement to express (hopefully) an
equivalent request.IEnumerable is more generic than IQueryable (though all instances of IQueryable implement IEnumerable) and only defines
a sequence. However, there are extension methods available within the
Enumerable class that define some query-type operators on that
interface and use ordinary code to evaluate these conditions.List is just an output format, and while it implements IEnumerable, is not directly related to querying.
有关详细信息,请查看以下链接:
iQuery、List和IEnumerator之间的区别?
更新
如果在下面的IRepository接口类中定义了一个过滤器
1 | IQueryable<T> Filter(Expression<Func<T, bool>> filter); |
您可以更改getEmployees方法,如下所示:
1 2 3 4 | public IQueryable<Employee> GetEmployees(int take, int skip) { return GetRepo<Employee>().Filter(p => p.IsDeleted == false).OrderBy(p => p.EmployeeNumber).Skip(10).Take(10); } |
原因是使查询延迟。