jQuery DataTables 服务器端数据处理--jQuery DataTables Plugin Meets C#

在读 使用 jQuery dataTables - 2 四种数据来源 的时候发现了这篇介绍在 C# 中结合 LINQ 使用 DataTables 进行服务端处理经验的文章:jQuery DataTables Plugin Meets C#

在调试文章中给出的例子的时候,遇到了下面3个异常:

  • 1 Expression of type 'System.Nullable`1[System.Int32]' cannot be used for return type 'System.Object'
    (类型为“System.Nullable`1[System.Int32]”的表达式不能用于返回类型“System.Object”)
  • 2 Cannot order by type 'System.Object'
    (无法按类型“System.Object”排序。)
  • 3 Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.
    (不能在查询运算符(Contains 运算符除外)的 LINQ to SQL 实现中使用本地序列。

1. 出现第一个异常是因为在客户端进行了按整数列(System.Nullable`1[System.Int32])排序(按照String列排序工作的很好)。这个可能是应为lambda表达式不提供值类型的自动封装,因此需要用Expression.TypeAs将该列的表达式类型显式封装成object:
可以将ApplySort中

var propertyExpr = Expression.Lambda<Func<T, dynamic>>(property, paramExpr);

换成:

var propertyExpr = Expression.Lambda<Func<T, dynamic>>(Expression.TypeAs( property,typeof(object)), paramExpr);

2. 当程序运行到Select扩展方法的时候出现了第二个异常。(如此看来,ApplySort中的排序并没有立即执行,而是推后到最终使用的时候才执行)
然而另外一个例子却并不会遇到这个问题:

var _List = new List<Item>
{
    new Item{ Name = "Smith", Value = 3},
    new Item{ Name = "Smith", Value = 2},
    new Item{ Name = "Wesson", Value = 1},
    new Item{ Name = "Wesson", Value = 4},
}.AsQueryable<Item>();

var _Type = typeof(Item);

// OrderBy
var _OrderByProperty = _Type.GetProperty("Value");
var _OrderByParameter = Expression.Parameter(typeof(Item), "x");
// OrderBy(x => x.Value)
var _OrderByBody = Expression.Property(_OrderByParameter, _OrderByProperty.Name);
var _OrderByLambda = Expression.Lambda<Func<Item, dynamic>>(Expression.TypeAs(_OrderByBody,typeof(object)),_OrderByParameter);
// apply the OrderBy
_List = _List.OrderByDescending(_OrderByLambda);

这可能是因为这里_List是本地序列的原因(IEnumerable<T>和IQueryable<T>的区别?)


当注释掉ApplySort再次运行又会遇到第三个异常(jQuery DataTables Plugin Meets C#之后的评论)
在Select之前用.ToList().AsQueryable()强制Linq 2 SQL先执行:问题得到解决。

var result = _queriable.Where(ApplyGenericSearch)
                       .Where(IndividualPropertySearch)
                       .Skip(skip)
                       .Take(take);
result = result.ToList().AsQueryable();
list.aaData = result.Select(SelectProperties).ToList();

然而这并没有解决排序的问题。

3. 从StackOverflow里面LINQ-Dynamic expression to OrderBy得到提示:将属性表达式树propertyExpr先编译再用于排序

问题便解决了!

if (string.IsNullOrEmpty(sortdir) || sortdir.Equals(ASCENDING_SORT, StringComparison.OrdinalIgnoreCase))
    _queriable = _queriable.OrderBy(propertyExpr.Compile()).AsQueryable<T>();
else
    _queriable = _queriable.OrderByDescending(propertyExpr.Compile()).AsQueryable<T>();

注:先编译之后再用于排序,Select之前也不用强制Linq 2 SQL先执行也不会出现第三个异常。

4. 最后,在客户端点击下一页的时候没有反应,也就是说即使有几页数据,每次点击下一页显示的还是第一页。(下一页按钮呈不可用状态)(jQuery DataTables Plugin Meets C#评论里面提到了)
要解决这个问题将

list.iTotalDisplayRecords = list.aaData.Count;

更改为:

list.iTotalDisplayRecords = list.iTotalRecords;

至此,JqueryTables 在服务器端进行数据处理的方式可以顺利使用了。

5. 总之,这些解决方法都是来自互联网,有些问题解决了但是具体原因还有待考究:

 

Linq系列

Linq 之Expression Tree再思考

使用 jQuery dataTables - 2 四种数据来源

jQuery DataTables Plugin Meets C#

Linq延时执行全面分析

Linq系列(2)——类型推断,IEnumerable<T>和IQueryable<T>

LINQ-Dynamic expression to OrderBy

posted @ 2013-04-08 20:22  Con-X  阅读(598)  评论(0编辑  收藏  举报