关于asp.net mvc:仅使用LINQ一次检索10条记录

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);
}

原因是使查询延迟。