LinqToSQL+;分页&x2B;动态排序?
我在使用带有分页+动态排序的LinqToSQL时遇到了一个问题。这是我的示例代码LinqToSQL+;分页&x2B;动态排序?,linq,linq-to-sql,Linq,Linq To Sql,我在使用带有分页+动态排序的LinqToSQL时遇到了一个问题。这是我的示例代码 Using db As New MyDataContext(connectionString) db.Log = new DebuggerWritter Dim result = db.User.OrderBy(Function(u) u.UserId) result = result.Skip((pageNo - 1) * pageSize).Take(pageSize)
Using db As New MyDataContext(connectionString)
db.Log = new DebuggerWritter
Dim result = db.User.OrderBy(Function(u) u.UserId)
result = result.Skip((pageNo - 1) * pageSize).Take(pageSize)
End Using
这是由LINQToSQL生成的SQL脚本,它仅用于检索特定的记录行
SELECT [t1].[UserId], [t1].[UserName]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[UserId]) AS [ROW_NUMBER], [t0].[UserId], [t0].[UserName]
FROM [dbo].[User] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]
但是如果我实现了动态排序
Using db As New MyDataContext(connectionString)
db.Log = new DebuggerWritter
Dim result = db.User
For Each s In sortExpressions
Dim expression As Func(Of User, Object) = Function(u) u.[GetType]().GetProperty(s.propertyName).GetValue(u, Nothing)
Select Case s.SortOrder
Case SortExpression.SortDirection.Ascending
result = result.OrderBy(expression).AsQueryable
Case SortExpression.SortDirection.Descending
result = result.OrderByDescending(expression).AsQueryable
End Select
Next
result = result.Skip((pageNo - 1) * pageSize).Take(pageSize)
End Using
这是这次生成的SQL脚本
SELECT [t0].[UserId], [t0].[UserName]
FROM [dbo].[User] AS [t0]
为什么分页控制脚本没有生成,排序也没有了??我实现动态排序的方式是错误的吗?或者LinqToSQL不支持分页+动态排序??
救命啊 您在代码中所做的将不起作用。然而,我有点惊讶LINQtoSQL没有抛出异常 在
result.OrderBy(expression)
中调用的OrderBy
方法是可枚举的.OrderBy
方法,而不是可查询的.OrderBy
方法。您已经注意到了这一点,因为它返回的对象是IEnumerable(Of User)
,而不是IQueryable(Of User)
。因此,您可以通过调用AsQueryable()
将其转换为IQueryable(Of User)
。但是,调用AsQyeryable无法工作。原因是LINQtoSQL处理表达式树(基本上就是IQueryable
)。表达式树可以动态组合,就像您已经使用result=result.Skip时所做的那样<但是,code>Enumerable
不适用于表达式树,而适用于委托,委托是编译的方法调用。虽然您可以将这样一个已编译的方法调用转换为IQueryable
,但LINQ to SQL无法对其进行分析,因为它仍然是已编译的代码(这需要内省来完成,而内省只支持作为反射器的专用工具)。在本例中,LINQtoSQL可能会忽略部分查询的完整顺序,因为它发现了一个无法处理的(已编译的)方法调用
因此,只有在执行以下操作时,您的解决方案才会起作用:
Dim expression As Expression(Of Func(Of User, [ExpectedKeyHere]) = _
... creation of the expression here ...
Select Case s.SortOrder
Case SortExpression.SortDirection.Ascending
result = result.OrderBy(expression)
Case SortExpression.SortDirection.Descending
result = result.OrderByDescending(expression)
End Select
然而,还有一件事。您似乎在一组sortExpressions
中循环。虽然可以附加已排序的集合,但必须使用result.ThenBy
或result.ThenBy降序调用已排序的集合。用结果调用它。OrderBy
将完全使用它;您将失去最初的排序顺序
长话短说,也许您应该尝试构建某种EntitySorter
对象,允许方法的调用方指定排序顺序。您的服务方式可能不是这样的(对不起,是C#):
publicstaticperson[]getallperson(IEntitySorter分拣机)
{
条件.Requires(分类器,“分类器”).IsNotNull();
使用(var db=ContextFactory.CreateContext())
{
IOrderedQueryable分类列表=
分拣机分拣(db.人员);
返回sortedList.ToArray();
}
}
,同样,它是C#,但我认为它会完全满足您的需要
祝你好运。你在代码中所做的不会起作用。然而,我有点惊讶LINQtoSQL没有抛出异常
在result.OrderBy(expression)
中调用的OrderBy
方法是可枚举的.OrderBy
方法,而不是可查询的.OrderBy
方法。您已经注意到了这一点,因为它返回的对象是IEnumerable(Of User)
,而不是IQueryable(Of User)
。因此,您可以通过调用AsQueryable()
将其转换为IQueryable(Of User)
。但是,调用AsQyeryable
无法工作。原因是LINQtoSQL处理表达式树(基本上就是IQueryable
)。表达式树可以动态组合,就像您已经使用result=result.Skip时所做的那样<但是,code>Enumerable
不适用于表达式树,而适用于委托,委托是编译的方法调用。虽然您可以将这样一个已编译的方法调用转换为IQueryable
,但LINQ to SQL无法对其进行分析,因为它仍然是已编译的代码(这需要内省来完成,而内省只支持作为反射器的专用工具)。在本例中,LINQtoSQL可能会忽略部分查询的完整顺序,因为它发现了一个无法处理的(已编译的)方法调用
因此,只有在执行以下操作时,您的解决方案才会起作用:
Dim expression As Expression(Of Func(Of User, [ExpectedKeyHere]) = _
... creation of the expression here ...
Select Case s.SortOrder
Case SortExpression.SortDirection.Ascending
result = result.OrderBy(expression)
Case SortExpression.SortDirection.Descending
result = result.OrderByDescending(expression)
End Select
然而,还有一件事。您似乎在一组sortExpressions
中循环。虽然可以附加已排序的集合,但必须使用result.ThenBy
或result.ThenBy降序调用已排序的集合。用结果调用它。OrderBy
将完全使用它;您将失去最初的排序顺序
长话短说,也许您应该尝试构建某种EntitySorter
对象,允许方法的调用方指定排序顺序。您的服务方式可能不是这样的(对不起,是C#):
publicstaticperson[]getallperson(IEntitySorter分拣机)
{
条件.Requires(分类器,“分类器”).IsNotNull();
使用(var db=ContextFactory.CreateContext())
{
IOrderedQueryable分类列表=
分拣机分拣(db.人员);
返回sortedList.ToArray();
}
}
,同样,它是C#,但我认为它会完全满足您的需要
祝你好运