使用IQueryable <t>和Expressions </t>与字符串值进行比较

时间:2011-02-22 23:12:42

标签: c# linq entity-framework-ctp5

对标题感到抱歉,但我真的想不出一个快速说出我想要的方法 - 如果你想到的话,有人可以把它改成更合适的吗?

我正在尝试将以下函数调用转换为表达式查询。

List.Compare("propretyName", ">1000");


public static IQueryable<T> Compare<T>(this IQueryable<T> source, string propertyName, string value) {
    Type type = typeof(T);
    ParameterExpression parameter = Expression.Parameter(type, "param");
    MemberExpression memberAccess = Expression.MakeMemberAccess(parameter, type.GetProperty(propertyName));

    string comparisonType = value.Substring(0, 1);
    value = value.Length > 0 ? value.Substring(1) : "0";

    decimal tmpvalue;
    decimal? result = decimal.TryParse(value, out tmpvalue) ? tmpvalue : (decimal?)null;
    ConstantExpression constant = Expression.Constant(result, typeof(decimal?));
    BinaryExpression comparisonExpression = Expression.GreaterThan(memberAccess, constant);
    switch (comparisonType) {
        case ">":
            comparisonExpression = Expression.GreaterThan(memberAccess, constant);
            break;
        case "<":
            comparisonExpression = Expression.LessThan(memberAccess, constant);
            break;
        case "=":
            comparisonExpression = Expression.Equal(memberAccess, constant);
            break;
    }

    Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(comparisonExpression, parameter);
    return source.Where(lambda);
}

以上是我写这个电话的方法。

底部的lambda似乎是正确的:{param => (param.propretyName > 1000)}

然而,它不起作用,我认为这是因为我正在处理的特定属性是decimal?所以它应该是{param => (param.propertyName.Value > 1000)}

有人可以帮助我使用Value而不是。这里有一些东西在逃避我。

我无法使用Where(string)方法,因为我正在使用Entity-Framework。

找到答案

public static IQueryable<T> Compare<T>(this IQueryable<T> source, string propertyName, string value) {
    Type type = typeof(T);
    ParameterExpression parameter = Expression.Parameter(type, "param");
    MemberExpression memberAccess = Expression.MakeMemberAccess(parameter, type.GetProperty(propertyName));

    //This is the added methods that results in the proper output
    PropertyInfo valProp = typeof(Nullable<decimal>).GetProperty("Value");
    memberAccess = Expression.MakeMemberAccess(memberAccess, valProp);

    string comparisonType = value.Substring(0, 1);
    value = value.Length > 0 ? value.Substring(1) : "0";

    decimal tmpvalue;
    decimal? result = decimal.TryParse(value, out tmpvalue) ? tmpvalue : (decimal?)null;
    ConstantExpression constant = Expression.Constant(tmpvalue);
    BinaryExpression comparisonExpression = Expression.GreaterThan(memberAccess, constant);
    switch (comparisonType) {
        case ">":
            comparisonExpression = Expression.GreaterThan(memberAccess, constant);
            break;
        case "<":
            comparisonExpression = Expression.LessThan(memberAccess, constant);
            break;
        case "=":
            comparisonExpression = Expression.Equal(memberAccess, constant);
            break;
    }

    Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(comparisonExpression, parameter);
    return source.Where(lambda);
}

1 个答案:

答案 0 :(得分:1)

为什么不使用现有的Dynamic LINQ library

myList.Where("propertyName > 1000");
相关问题