Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LinqToSQL+;分页&x2B;动态排序?_Linq_Linq To Sql - Fatal编程技术网

LinqToSQL+;分页&x2B;动态排序?

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)

我在使用带有分页+动态排序的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)      
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#,但我认为它会完全满足您的需要

祝你好运