0

列名でajax応答グリッドを並べ替える必要があります。列の値は、文字列として格納されている数値です。

いくつかの些細なクラスを考えてみましょう(実際の状況では、このクラスを変更する可能性はありません):

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);
    }
4

1 に答える 1

3

Expression.Call()を呼び出して、メソッドを呼び出す式ノードを作成できます。

Expression.Call(typeof(Double), "Parse", null, property)
于 2012-11-19T16:45:42.717 に答える