0

文字列パラメーターからラムダ式を構築できるヘルパー クラスを作成し、これを使用してクエリ結果をフィルター処理できます。

しかし、LINQ.Expressions.Expression に Contains メソッドがないという問題はほとんどありません。

これは私のコードです:

 string member = d.Member;
        object value = d.Value;

        System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");

        foreach (var property in member.Split('.'))
        {
            expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
        }

        ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, typeof(string));

        BinaryExpression b = null;

        switch (d.Operator)
        {
            case FilterOperator.IsEqualTo:

                b = System.Linq.Expressions.Expression.Equal(expression, c);

                break;

            case FilterOperator.Contains:

                b = GetExpression<T>(expression.ToString(), value.ToString()).Body as BinaryExpression;

                break;

            case FilterOperator.IsGreaterThanOrEqualTo:

                b = System.Linq.Expressions.Expression.GreaterThanOrEqual(expression, c);

                break;

            case FilterOperator.IsLessThanOrEqualTo:

                b = System.Linq.Expressions.Expression.LessThanOrEqual(expression, c);

                break;
        }


        CriteriaCollection.Add(b);

static Expression<Func<T, bool>> GetExpression<T>(string propertyName, string propertyValue)
    {
        var parameterExp = Expression.Parameter(typeof(T), "type");
        var propertyExp = Expression.Property(parameterExp, propertyName);
        MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
        var someValue = Expression.Constant(propertyValue, typeof(string));
        var containsMethodExp = Expression.Call(propertyExp, method, someValue);

        return BinaryExpression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
    }

それはうまくいくはずですが、ExpressionをBinaryExpressionに変換するにはどうすればよいですか?

誰かがこれを知っているか、機能している他の解決策を知っていますか?

4

2 に答える 2

-2
 public class FilterExpressionHelper<T> where T : class
{
    public FilterExpressionHelper()
    {
        CriteriaCollection = new List<BinaryExpression>();
    }

    public List<BinaryExpression> CriteriaCollection { get; set; }

    public Expression<Func<T, bool>> NoFilterExpression { get; set; }

    public void RemoveFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d)
    {
        string member = d.Member;
        object value = d.Value;

        System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");

        foreach (var property in member.Split('.'))
        {
            expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
        }

        ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, typeof(string));
        BinaryExpression b = System.Linq.Expressions.Expression.Equal(expression, c);

        BinaryExpression expr = CriteriaCollection.Where(cr => cr.Right.ToString() == b.Right.ToString()).FirstOrDefault();

        CriteriaCollection.Remove(expr);
    }

    public void AddFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d)
    {
        string member = d.Member;
        object value = d.Value;

        System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");

        foreach (var property in member.Split('.'))
        {
            expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
        }

        ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, value.GetType());

        BinaryExpression b = null;

        switch (d.Operator)
        {
            case FilterOperator.IsEqualTo:

                b = System.Linq.Expressions.Expression.Equal(expression, c);

                break;

            case FilterOperator.Contains:

                //b = GetExpression<T>(expression.ToString(), value.ToString()).Body as BinaryExpression;


                break;

            case FilterOperator.IsGreaterThanOrEqualTo:

                b = System.Linq.Expressions.Expression.GreaterThanOrEqual(expression, c);

                break;

            case FilterOperator.IsLessThanOrEqualTo:


                    b = System.Linq.Expressions.Expression.LessThanOrEqual(expression, c);

                break;
        }


        CriteriaCollection.Add(b);
    }

    public  Expression<Func<T, bool>> GetLambdaExpression()
    {
        ParameterExpression e = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");

        var orderedList = CriteriaCollection.OrderBy(cr => cr.Left.ToString()).ToList();

        var disctinctValues = CriteriaCollection.Distinct(new BinaryExpressionComparer()).ToList();

        List<BinaryExpression> orElseExpressionList = new List<BinaryExpression>();

        foreach (var value in disctinctValues)
        {
            System.Linq.Expressions.BinaryExpression expression = null;

            foreach (var criteria in orderedList.Where(cr => cr.Left.ToString().Equals(value.Left.ToString())))
            {
                if (expression == null)
                {
                    expression = criteria;
                }
                else
                {
                    if (expression.Left.ToString() == criteria.Left.ToString())
                        expression = System.Linq.Expressions.BinaryExpression.OrElse(expression, criteria);
                    else
                        expression = System.Linq.Expressions.BinaryExpression.AndAlso(expression, criteria);

                }
            }

            orElseExpressionList.Add(expression);
        }

        System.Linq.Expressions.BinaryExpression expressionAnd = null;

        foreach (var ex in orElseExpressionList)
        {
            if (expressionAnd == null)
            {
                expressionAnd = ex;
            }
            else
            {
                expressionAnd = System.Linq.Expressions.BinaryExpression.AndAlso(expressionAnd, ex);
            }
        }

        if (expressionAnd != null)
        {
            return System.Linq.Expressions.Expression.Lambda<Func<T, bool>>(expressionAnd, e);
        }
        else
        {
            return NoFilterExpression;
        }
    }

    static Expression<Func<T, bool>> GetExpression<T>(string propertyName, string propertyValue)
    {
        var parameterExp = Expression.Parameter(typeof(T), "type");
        var propertyExp = Expression.Property(parameterExp, propertyName);
        MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
        var someValue = Expression.Constant(propertyValue, typeof(string));
        var containsMethodExp = Expression.Call(propertyExp, method, someValue);

        return BinaryExpression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
    }

    private static System.Linq.Expressions.BinaryExpression Like(Expression lhs, Expression rhs)
    {
        //typeof(string).GetMethod("Contains", new Type[] { typeof(string) }, null);

        Expression expression = Expression.Call(
            typeof(FileInfoHelper).GetMethod("Like",
                BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
                , lhs, rhs);

        return expression as BinaryExpression;
    }

    class BinaryExpressionComparer : IEqualityComparer<BinaryExpression>
    {
        #region IEqualityComparer<Contact> Members

        public bool Equals(BinaryExpression x, BinaryExpression y)
        {
            return x.Left.ToString().Equals(y.Left.ToString());
        }

        public int GetHashCode(BinaryExpression obj)
        {
            return obj.Left.ToString().GetHashCode();
        }

        #endregion
    }
}
于 2012-07-09T12:20:46.623 に答える