Expression

Expression<Func<T,bool>>是表达式树，我们可以通过它来分析我们的委托中的函数。当调用Compile方法后就会变成委托，才能执行。

Func<T,bool>只是一个普通的委托。

` public class Staff    {        public string Name { get; set; }        public int Age { get; set; }        public string Code { get; set; }        public DateTime? Birthday { get; set; }        public bool Deletion { get; set; }    }`

`  class Program    {        static void Main(string[] args)        {            FindAs<Staff>(x => x.Code == "张三" && x.Name.Contains("张"));        }        public static List<T> FindAs<T>(Expression<Func<T, bool>> func)        {            //将func转换成对应数据库的查询条件，然后执行查询            return null;//将结果返回        }    }`

` class Program    {        static void Main(string[] args)        {            FindAs<Staff>(x => x.Code == "张三" && x.Name.Contains("张"));            FindAs<Staff>(x => x.Age <= 12 && x.Name.Contains("张"));            Console.ReadKey();        }        public static List<T> FindAs<T>(Expression<Func<T, bool>> func)        {            BinaryExpression Binary = func.Body as BinaryExpression;            string left = ResovleFunc(Binary.Left);            string right = ResovleLinqToObject(Binary.Right);            string oper = GetOperator(Binary.NodeType);            string sql = string.Format("select * from {0} where {1}", typeof(T).Name, left + oper + right);            Console.WriteLine(sql);            return null;//将结果返回        }        //解析一般的条件，例如x=>x.name==xxxx   x.age==xxx        public static string ResovleFunc(Expression express)        {            var inner = express as BinaryExpression;            string Name = (inner.Left as MemberExpression).Member.Name;            object Value = (inner.Right as ConstantExpression).Value;            var Operator = GetOperator(inner.NodeType);            string Result = string.Format("({0} {1} '{2}')", Name, Operator, Value);            return Result;        }        //解析linq to object这类扩展方法        public static string ResovleLinqToObject(Expression expression)        {            var MethodCall = expression as MethodCallExpression;            var MethodName = MethodCall.Method.Name;            if (MethodName == "Contains")            {                object Temp_Vale = (MethodCall.Arguments[0] as ConstantExpression).Value;                string Value = string.Format("%{0}%", Temp_Vale);                string Name = (MethodCall.Object as MemberExpression).Member.Name;                string Result = string.Format("{0} like '{1}'", Name, Value);                return Result;            }            return null;        }        public static string GetOperator(ExpressionType expressiontype)        {            switch (expressiontype)            {                case ExpressionType.And:                    return "and";                case ExpressionType.AndAlso:                    return "and";                case ExpressionType.Or:                    return "or";                case ExpressionType.OrElse:                    return "or";                case ExpressionType.Equal:                    return "=";                case ExpressionType.NotEqual:                    return "<>";                case ExpressionType.LessThan:                    return "<";                case ExpressionType.LessThanOrEqual:                    return "<=";                case ExpressionType.GreaterThan:                    return ">";                case ExpressionType.GreaterThanOrEqual:                    return ">=";                default:                    throw new Exception(string.Format("不支持{0}此种运算符查找！" + expressiontype));            }        }    }`

` public class ResolveExpress    {        public Dictionary<string, object> Argument;        public string SqlWhere;        public SqlParameter[] Paras;        /// <summary>        /// 解析lamdba，生成Sql查询条件        /// </summary>        /// <param name="expression"></param>        /// <returns></returns>        public void ResolveExpression(Expression expression)        {            this.Argument = new Dictionary<string, object>();            this.SqlWhere = Resolve(expression);            this.Paras = Argument.Select(x => new SqlParameter(x.Key, x.Value)).ToArray();        }        private string Resolve(Expression expression)        {            if (expression is LambdaExpression)            {                LambdaExpression lambda = expression as LambdaExpression;                expression = lambda.Body;                return Resolve(expression);            }            if (expression is BinaryExpression)            {                BinaryExpression binary = expression as BinaryExpression;                if (binary.Left is MemberExpression && binary.Right is ConstantExpression)//解析x=>x.Name=="123" x.Age==123这类                    return ResolveFunc(binary.Left, binary.Right, binary.NodeType);                if (binary.Left is MethodCallExpression && binary.Right is ConstantExpression)//解析x=>x.Name.Contains("xxx")==false这类的                {                    object value = (binary.Right as ConstantExpression).Value;                    return ResolveLinqToObject(binary.Left, value, binary.NodeType);                }                if (binary.Left is MemberExpression && binary.Right is MemberExpression)//解析x=>x.Date==DateTime.Now这种                {                    LambdaExpression lambda = Expression.Lambda(binary.Right);                    Delegate fn = lambda.Compile();                    ConstantExpression value = Expression.Constant(fn.DynamicInvoke(null), binary.Right.Type);                    return ResolveFunc(binary.Left, value, binary.NodeType);                }            }            if (expression is UnaryExpression)            {                UnaryExpression unary = expression as UnaryExpression;                if (unary.Operand is MethodCallExpression)//解析!x=>x.Name.Contains("xxx")或!array.Contains(x.Name)这类                    return ResolveLinqToObject(unary.Operand, false);                if (unary.Operand is MemberExpression && unary.NodeType == ExpressionType.Not)//解析x=>!x.isDeletion这样的                 {                    ConstantExpression constant = Expression.Constant(false);                    return ResolveFunc(unary.Operand, constant, ExpressionType.Equal);                }            }            if (expression is MemberExpression && expression.NodeType == ExpressionType.MemberAccess)//解析x=>x.isDeletion这样的             {                MemberExpression member = expression as MemberExpression;                ConstantExpression constant = Expression.Constant(true);                return ResolveFunc(member, constant, ExpressionType.Equal);            }            if (expression is MethodCallExpression)//x=>x.Name.Contains("xxx")或array.Contains(x.Name)这类            {                MethodCallExpression methodcall = expression as MethodCallExpression;                return ResolveLinqToObject(methodcall, true);            }            var body = expression as BinaryExpression;            if (body == null)                throw new Exception("无法解析" + expression);            var Operator = GetOperator(body.NodeType);            var Left = Resolve(body.Left);            var Right = Resolve(body.Right);            string Result = string.Format("({0} {1} {2})", Left, Operator, Right);            return Result;        }        /// <summary>        /// 根据条件生成对应的sql查询操作符        /// </summary>        /// <param name="expressiontype"></param>        /// <returns></returns>        private string GetOperator(ExpressionType expressiontype)        {            switch (expressiontype)            {                case ExpressionType.And:                    return "and";                case ExpressionType.AndAlso:                    return "and";                case ExpressionType.Or:                    return "or";                case ExpressionType.OrElse:                    return "or";                case ExpressionType.Equal:                    return "=";                case ExpressionType.NotEqual:                    return "<>";                case ExpressionType.LessThan:                    return "<";                case ExpressionType.LessThanOrEqual:                    return "<=";                case ExpressionType.GreaterThan:                    return ">";                case ExpressionType.GreaterThanOrEqual:                    return ">=";                default:                    throw new Exception(string.Format("不支持{0}此种运算符查找！" + expressiontype));            }        }        private string ResolveFunc(Expression left, Expression right, ExpressionType expressiontype)        {            var Name = (left as MemberExpression).Member.Name;            var Value = (right as ConstantExpression).Value;            var Operator = GetOperator(expressiontype);            string CompName = SetArgument(Name, Value.ToString());            string Result = string.Format("({0} {1} {2})", Name, Operator, CompName);            return Result;        }        private string ResolveLinqToObject(Expression expression, object value, ExpressionType? expressiontype = null)        {            var MethodCall = expression as MethodCallExpression;            var MethodName = MethodCall.Method.Name;            switch (MethodName)//这里其实还可以改成反射调用，不用写switch            {                case "Contains":                    if (MethodCall.Object != null)                        return Like(MethodCall);                    return In(MethodCall, value);                case "Count":                    return Len(MethodCall, value, expressiontype.Value);                case "LongCount":                    return Len(MethodCall, value, expressiontype.Value);                default:                    throw new Exception(string.Format("不支持{0}方法的查找！", MethodName));            }        }        private string SetArgument(string name, string value)        {            name = "@" + name;            string temp = name;            while (Argument.ContainsKey(temp))            {                int code = Guid.NewGuid().GetHashCode();                if (code < 0)                    code *= -1;                temp = name + code;            }            Argument[temp] = value;            return temp;        }        private string In(MethodCallExpression expression, object isTrue)        {            var Argument1 = (expression.Arguments[0] as MemberExpression).Expression as ConstantExpression;            var Argument2 = expression.Arguments[1] as MemberExpression;            var Field_Array = Argument1.Value.GetType().GetFields().First();            object[] Array = Field_Array.GetValue(Argument1.Value) as object[];            List<string> SetInPara = new List<string>();            for (int i = 0; i < Array.Length; i++)            {                string Name_para = "InParameter" + i;                string Value = Array[i].ToString();                string Key = SetArgument(Name_para, Value);                SetInPara.Add(Key);            }            string Name = Argument2.Member.Name;            string Operator = Convert.ToBoolean(isTrue) ? "in" : " not in";            string CompName = string.Join(",", SetInPara);            string Result = string.Format("{0} {1} ({2})", Name, Operator, CompName);            return Result;        }        private string Like(MethodCallExpression expression)        {            object Temp_Vale = (expression.Arguments[0] as ConstantExpression).Value;            string Value = string.Format("%{0}%", Temp_Vale);            string Name = (expression.Object as MemberExpression).Member.Name;            string CompName = SetArgument(Name, Value);            string Result = string.Format("{0} like {1}", Name, CompName);            return Result;        }        private string Len(MethodCallExpression expression, object value, ExpressionType expressiontype)        {            object Name = (expression.Arguments[0] as MemberExpression).Member.Name;            string Operator = GetOperator(expressiontype);            string CompName = SetArgument(Name.ToString(), value.ToString());            string Result = string.Format("len({0}){1}{2}", Name, Operator, CompName);            return Result;        }    }`

` static void Main(string[] args)        {            string[] Names = { "Andy", "Amy", "Mike" };            Expression<Func<Staff, bool>> func = x => (!Names.Contains(x.Name) && (x.Name == "A" || x.Name.Count() > 5));            ResolveExpress resolve = new ResolveExpress();            resolve.ResolveExpression(func);            Console.WriteLine(resolve.SqlWhere);            foreach (var item in resolve.Paras)            {                Console.WriteLine(item.ParameterName + ":" + item.Value);            }            Console.ReadKey();        }`

string[] Names={"Andy","Amy","Mike"};

1.）x => Names.Contains(x.Name);

2.）x => Names.Contains(x.Name)==false;

3.）x => !Names.Contains(x.Name);

1的话会看成是一个静态方法（MethodCallExpression）

2的话会看成是一个2元运算（BinaryExpression）

3的话会看成是一个1元运算（UnaryExpression）

x=>x.Birthday<DateTime.Now;

string name="123";

x=>x.Name==name;

x=>x.Name=="123"

IEnumerable和IQueryable有什么不同？

IQueryable中有3个属性。

Type是类型。

Expresstion是表达式。

CreateQuery是创建查询条件

Execute是执行查询（通常在GetEnumerator()中调用）