2012-11-19 2 views
0

아약스 응답 표를 열 이름별로 정렬해야합니다. 열 값은 문자열로 저장된 숫자입니다.변환을 사용하여 LambdaExpression을 구성하는 방법

의 몇 가지 사소한 클래스 (실제 상황에서이 클래스를 수정 할 수 없음) 가정 해 봅시다 :

class TestObject 
{ 
    public TestObject(string v) 
    { 
     this.Value = v; 
    } 
    public string Value { get; set; } 
} 

후 간단한 테스트 :

분명 존재하지 않는
[Test] 
public void LambdaConstructionTest() 
{ 
    var queryable = new List<TestObject> 
        { 
         new TestObject("5"), 
         new TestObject("55"), 
         new TestObject("90"), 
         new TestObject("9"), 
         new TestObject("09"), 
         new TestObject("900"), 
        }.AsQueryable(); 

    var sortingColumn = "Value"; 

    ParameterExpression parameter = Expression.Parameter(queryable.ElementType); 

    MemberExpression property = Expression.Property(parameter, sortingColumn); 
    //// tried this one: var c = Expression.Convert(property, typeof(double)); 

     LambdaExpression lambda = Expression.Lambda(property, parameter); //// constructs: o=>o.Value 

     var callExpression = Expression.Call(typeof (Double), "Parse", null, property); 

     var methodCallExpression = Expression.Call(
      typeof(Queryable), 
      "OrderBy", 
      new[] { queryable.ElementType, property.Type }, 
      queryable.Expression, 
      Expression.Quote(lambda)); // works, but sorts by string values. 
      //Expression.Quote(callExpression)); // getting: System.ArgumentException {"Quoted expression must be a lambda"} 

     var querable = queryable.Provider.CreateQuery<TestObject>(methodCallExpression); 

     // return querable; // <- this is the return of what I need. 
} 

미안 내 첫 번째 @SLaks 답은 올바른 답변으로 게시하지만이 경우 올바른 람다 식을 구성하는 방법을 모르겠습니다.

마지막으로 발견 컬럼에 문자열을 가지고 있으며, 변환 된 double 값을 기준으로 정렬해야하는 사람을위한 좋은 솔루션 : (@SLaks에 대한 특별 감사가 자신의 게시물이 눈 오프너이었다) :

[Test] 
    public void LambdaConstructionTest2() 
    { 
     // GIVEN 
     var queryable = new List<TestObject> 
          { 
           new TestObject("5"), 
           new TestObject("55"), 
           new TestObject("90"), 
           new TestObject("9"), 
           new TestObject("09"), 
           new TestObject("900"), 
          }.AsQueryable(); 

     var sortingColumn = "Value"; 

     // WHEN 
     ParameterExpression parameter = Expression.Parameter(queryable.ElementType); 

     MemberExpression property = Expression.Property(parameter, sortingColumn); 

     MethodCallExpression callExpression = Expression.Call(typeof (Double), "Parse", null, property); 

     LambdaExpression lambda = Expression.Lambda(callExpression, parameter); // = {Param_0 => Parse(Param_0.Value)} 

     UnaryExpression unaryExpression = Expression.Quote(lambda); // Expression<Func<TestObject,double>> = {Param_0 => Parse(Param_0.Value)} 

     var methodCallExpression = Expression.Call(
      typeof (Queryable), 
      "OrderByDescending", 
      new[] { queryable.ElementType, lambda.ReturnType }, 
      queryable.Expression, 
      unaryExpression); 

     var querable = queryable.Provider.CreateQuery<TestObject>(methodCallExpression); 

     // THEN 
     var expectedMaxValue = queryable.Max(x => Convert.ToDouble(x.Value)); 
     var expectedMinValue = queryable.Min(x => Convert.ToDouble(x.Value)); 

     var list = querable.ToList(); 

     var actualMaxValue = Convert.ToDouble(list.First().Value); 
     var actualMinValue = Convert.ToDouble(list.Last().Value); 
     Assert.AreEqual(expectedMaxValue, actualMaxValue); 
     Assert.AreEqual(expectedMinValue, actualMinValue); 
    } 

답변

2

당신에게 Expression.Call()을 호출하여 메소드를 호출하는 표현식 노드를 작성할 수 있습니다.

Expression.Call(typeof(Double), "Parse", null, property) 
+0

신속한 답변을 보내 주셔서 감사합니다. 익스프레션 콜에서 익스프레션 콜을 구성하는 방법을 알지 못해서 익스프레션 트리가있는 것 같아요. 거기에 모든 내용을 공개하는 내 게시물을 편집했습니다. – nerijus

관련 문제