2012-05-03 95 views
2

我有一个小问题,我会尽力详细解释这一点。LINQ - 动态表达式OrderBy

在我的系统上,我有一个与EF 4.1一起工作的Generic Repository。 一切都很好,但我在某些情况下遇到问题,我需要通过一些querys来做动态orderBy。

我通过参数的“字符串”表示在我的类的字段收到,做ORDERBY(如“ID”或“描述”)

一些代码部分:

 public class SomeClass 
     { 
      public int id { get; set; } 
      public string description { get; set; } 
     } 

     // First we define the parameter that we are going to use 
     // in our OrderBy clause. This is the same as "(parameter =>" 
     // in the example above. 
     var param = Expression.Parameter(typeof(SomeClass), "parameter"); 

     // Now we'll make our lambda function that returns the 
     // request.SortingName property by it's name. 
     var expression = Expression.Lambda<Func<SomeClass, int>>(Expression.Property(param, request.SortingName), param); 

那么,如果“request.SortingName”是类型“int”(id),但是如果我想通过“string”(描述)或其他类型创建orderBy,则此代码无效。

我改变的表达,使用“对象”:

 var expression = Expression.Lambda<Func<SomeClass, object>>(Expression.Property(param, request.SortingName), param); 

但是当我运行的代码,编译器会引发下一个异常:类型System.Int32'的 表达不能被用于返回类型“System.Object的”

如果该属性字符串类型,异常的类型为“System.String”的 表达不能被用于返回类型“System.Object的”

换句话说代码没有按不适用于“对象”类型。

任何人都知道我该如何解决这个问题?

谢谢你的时间。

+0

不能使用对目标的反射式和查找基于你有,并确定从正确的类型名称的属性? –

+1

[动态LINQ OrderBy](http://stackoverflow.com/questions/41244/dynamic-linq-orderby)可能会帮助 – Eranga

回答

6

下面是我如何使用EF4和我在标准开发库中创建的一些通用方法进行动态排序和分页。重要的是您用于为SortBy方法创建Lambda表达式的第二位代码。

public enum SqlOrderByDirecton 
{ 
    ASC, 
    DESC 
} 

//Derive Lambda Expression from string 

string sortByKey = "BusinessId"; 
string value = "DESC"; 

var p = Expression.Parameter(typeof(T)); 

this.SortBy = Expression.Lambda<Func<T, dynamic>>(Expression.TypeAs(Expression.Property(p, sortByKey), typeof(object)), p).Compile(); 

this.SortOrder = (DevCore.SqlOrderByDirecton)Enum.Parse(typeof(DevCore.SqlOrderByDirecton), value, true); 

public static List<T> SortAndPaginate<T>(IEnumerable<T> query, 
              Func<T, object> sortBy, 
              SqlOrderByDirecton sortOrder, 
              int rowLimit, 
              int startRecord, 
              out int recordCount) 
    { 
     recordCount = query.Count(); 

     List<T> list = new List<T>(); 

     if (sortOrder == SqlOrderByDirecton.ASC) 
     { 
      list = query.OrderBy(sortBy).Skip(startRecord).Take(rowLimit).ToList(); 
     } 
     else 
     { 
      list = query.OrderByDescending(sortBy).Skip(startRecord).Take(rowLimit).ToList(); 
     } 

     return list; 
    } 
+0

好!我修改了我的代码: Expression.Lambda >(Expression.TypeAs(Expression.Property(param,request.SortingName),typeof(object)),param); 然后我做.Compile();在我的Repository上,它的工作非常完美。 但是...如果我不'编译'查询不起作用。你知道什么是解释吗? – HolloW

+0

@HolloW我不是100%确定这是为什么 - 我最初从我问的问题,它的工作,我没有看到它的任何进一步的代码 - http://stackoverflow.com/questions/9756407/ fun-product-object-property – Rob

+0

@HolloW:这个答案至少值得赞扬:) –