Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq 二进制表达式包含方法_Linq_C# 4.0_Expression Trees - Fatal编程技术网

Linq 二进制表达式包含方法

Linq 二进制表达式包含方法,linq,c#-4.0,expression-trees,Linq,C# 4.0,Expression Trees,我创建了一个helper类,它能够从字符串参数构建lambda表达式,我可以使用它过滤查询结果 但是我有一个小问题,LINQ.Expressions.Expression没有Contains方法 这是我的代码: string member = d.Member; object value = d.Value; System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expr

我创建了一个helper类,它能够从字符串参数构建lambda表达式,我可以使用它过滤查询结果

但是我有一个小问题,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);
    }
字符串成员=d.成员;
对象值=d.值;
System.Linq.Expressions.Expression=System.Linq.Expressions.Expression.Parameter(typeof(T),“e”);
foreach(member.Split('.')中的var属性)
{
expression=System.Linq.Expressions.expression.PropertyOrField(expression,property);
}
ConstantExpression c=System.Linq.Expressions.Expression.Constant(value,typeof(string));
二进制表达式b=null;
开关(d.操作员)
{
case FilterOperator.IsEqualTo:
b=System.Linq.Expressions.Expression.Equal(表达式c);
打破
案例过滤器操作器。包含:
b=GetExpression(expression.ToString(),value.ToString())。主体为二进制表达式;
打破
案例过滤器Operator.Is大于或等于:
b=System.Linq.Expressions.Expression.GreaterThanOrEqual(表达式,c);
打破
案例过滤器Operator.islessthan或equalto:
b=System.Linq.Expressions.Expression.lessthanRequal(表达式,c);
打破
}
标准收集。添加(b);
静态表达式GetExpression(string propertyName、string propertyValue)
{
var parameterExp=表达式参数(typeof(T),“type”);
var propertyExp=Expression.Property(parameterExp,propertyName);
MethodInfo method=typeof(string).GetMethod(“Contains”,new[]{typeof(string)});
var someValue=表达式.常量(propertyValue,typeof(字符串));
var containsMethodExp=Expression.Call(propertyExp,method,someValue);
返回BinaryExpression.Lambda(containsMethodExp,parameterExp);
}
这应该是可行的,但是如何将表达式转换为二进制表达式呢

有人知道这一点,或者知道其他正在运行的解决方案吗?

公共类筛选器ExpressionHelper其中T:class
 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
    }
}
{ 公共筛选器ExpressionHelper() { CriteriaCollection=新列表(); } 公共列表标准集合{get;set;} 公共表达式NoFilterExpression{get;set;} public void RemoveFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d) { 字符串成员=d.成员; 对象值=d.值; System.Linq.Expressions.Expression=System.Linq.Expressions.Expression.Parameter(typeof(T),“e”); foreach(member.Split('.')中的var属性) { 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(表达式c); 二进制表达式expr=CriteriaCollection.Where(cr=>cr.Right.ToString()==b.Right.ToString()).FirstOrDefault(); 标准集合。删除(expr); } public void AddFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d) { 字符串成员=d.成员; 对象值=d.值; System.Linq.Expressions.Expression=System.Linq.Expressions.Expression.Parameter(typeof(T),“e”); foreach(member.Split('.')中的var属性) { expression=System.Linq.Expressions.expression.PropertyOrField(expression,property); } ConstantExpression c=System.Linq.Expressions.Expression.Constant(value,value.GetType()); 二进制表达式b=null; 开关(d.操作员) { case FilterOperator.IsEqualTo: b=System.Linq.Expressions.Expression.Equal(表达式c); 打破 案例过滤器操作器。包含: //b=GetExpression(expression.ToString(),value.ToString())。主体为二进制表达式; 打破 案例过滤器Operator.Is大于或等于: b=System.Linq.Expressions.Expression.GreaterThanOrEqual(表达式,c); 打破 案例过滤器Operator.islessthan或equalto: b=System.Linq.Expressions.Expression.lessthanRequal(表达式,c); 打破 } 标准收集。添加(b); } 公共表达式GetLambdaExpression() { ParameterExpression e=System.Linq.Expressions.Expression.Parameter(typeof(T),“e”); var orderedList=CriteriaCollection.OrderBy(cr=>cr.Left.ToString()).ToList(); var disctinctValues=CriteriaCollection.Distinct(新的BinaryExpressionComparer()).ToList(); List ORELSExpressionList=新列表(); foreach(disctinctValues中的var值) { System.Linq.Expressions.BinaryExpression=null; foreach(orderedList.Where(cr=>cr.Left.ToString().Equals(value.Left.ToString()))中的var条件) { if(表达式==null) { 表达式=标准; } 其他的 { if(expression.Left.ToString()==criteria.Left.ToString()) expression=System.Linq.Expressions.BinaryExpression.OrElse(表达式,条件); 其他的 expression=System.Linq.Expressions.BinaryExpression.AndAlso(表达式,条件); } } 添加(表达式); } System.Linq.Expressions.BinaryExpression expression and=null; foreach(OrelSexpressionList中的var ex) { if(expressionAnd==null)
public static bool Containss(string text, string text2)
{
    return text.Contains(text2, StringComparison.OrdinalIgnoreCase);
}
MethodInfo method = typeof(StackOverflowAnswer).GetMethod("Containss", new[] { typeof(string), typeof(string) });
var constainsExp = Expression.MakeBinary(ExpressionType.Equal, Expression.Constant("FULL TEXT"), Expression.Constant("TEXT"), false, method);
class StackOverflowAnswer
{
    static void Main()
    {
        ParameterExpression parameter = Expression.Parameter(typeof(Student), typeof(Student).Name);

        var exp1 = GetBinaryExpression(parameter, "Name", "Foo");
        var exp2 = GetBinaryExpression(parameter, "Name", "Bar");
        BinaryExpression[] expressions = new BinaryExpression[] { exp1, exp2 };

        var bin = CombineExpressions(expressions, parameter);
        var func = Expression.Lambda<Func<Student, bool>>(bin, parameter);
        var exp = func.Compile();

        Student student = new Student { Name = "Foo Bar" };

        var x = exp(student);

        Console.WriteLine(x);
    }

    public static BinaryExpression GetBinaryExpression(ParameterExpression parameter, string property, object comparissonValue)
    {
        MemberExpression member = Expression.Property(parameter, property);
        ConstantExpression constant = Expression.Constant(comparissonValue, comparissonValue.GetType());

        MethodInfo method = typeof(StackOverflowAnswer).GetMethod("Containss", new[] { typeof(string), typeof(string) });
        var containsExp = Expression.MakeBinary(ExpressionType.Equal, member, constant, false, method);
        return containsExp ;
    }

    public static BinaryExpression CombineExpressions(BinaryExpression[] expressions, ParameterExpression parameter)
    {
        bool first = true;
        BinaryExpression expFull = expressions[0];
        foreach (BinaryExpression item in expressions)
        {
            if (first)
                first = false;
            else
            {
                expFull = Expression.AndAlso(expFull, item);
            }
        }
        return expFull;
    }

    internal class Student
    {
        public string Name { get; set; }
    }
}