Expression <Func <T, bool> > CreateLambdaBinary(CRLExpression expression) { var left = expression.Left; var right = expression.Right; var creater = new LambdaCreater <T>(); var type = expression.ExpressionType; var dic = new Dictionary <string, ExpressionHandler>(); dic.Add("Equal", creater.Equal); dic.Add("NotEqual", creater.NotEqual); dic.Add("Greater", creater.Greater); dic.Add("Less", creater.Less); dic.Add("GreaterThan", creater.GreaterThan); dic.Add("LessThan", creater.LessThan); //todo 更多方法解析 if (!dic.ContainsKey(type)) { throw new CRLException("没有对应的运算方法 " + type); } if (left.Type == CRLExpressionType.MethodCall)//按方法运算 如 b.NameSubstring,Indexof(0,1)=="123" { //按属性的子方法 var left2 = CreateLambdaMethodCall2(left); var value = ObjectConvert.ConvertObject(left2.Type, right.Data); return(dic[type](left2, value)); } else//按属性运算 如b.Id==1 { var member = creater.CreatePropertyExpression(left.Data.ToString()); return(dic[type](member, right.Data)); } }
Expression <Func <T, bool> > CreateLambdaTree(CRLExpression expression) { var expression1 = CreateLambda(expression.Left); var expression2 = CreateLambda(expression.Right); switch (expression.ExpType) { case ExpressionType.AndAlso: return(expression1.Compose(expression2, Expression.AndAlso)); case ExpressionType.OrElse: return(expression1.Compose(expression2, Expression.OrElse)); case ExpressionType.And: return(expression1.Compose(expression2, Expression.And)); case ExpressionType.Or: return(expression1.Compose(expression2, Expression.Or)); } //if (expression.ExpressionType == "AndAlso") //{ // return expression1.Compose(expression2, Expression.AndAlso); //} //else //{ // return expression1.Compose(expression2, Expression.OrElse); //} return(null); }
FilterData RouteCRLExpression(CRLExpression.CRLExpression exp) { if (exp.Type == CRLExpression.CRLExpressionType.Binary || exp.Type == CRLExpression.CRLExpressionType.Tree)//表示二元运算 { return(BinaryCRLExpression(exp.Left, exp.Right, exp.ExpType)); } else if (exp.Type == CRLExpression.CRLExpressionType.MethodCall) { var methodInfo = exp.Data as CRLExpression.MethodCallObj; var left = new CRLExpression.CRLExpression() { ExpType = methodInfo.ExpressionType, Type = CRLExpression.CRLExpressionType.MethodCallArgs, Data = methodInfo }; var right = new CRLExpression.CRLExpression() { ExpType = methodInfo.ExpressionType, Type = CRLExpression.CRLExpressionType.MethodCallArgs, Data = methodInfo.Args }; return(BinaryCRLExpression(left, right, methodInfo.ExpressionType)); } //按值 return(new FilterData() { Data = exp.Data, Type = exp.Type }); }
public CRLExpression.CRLExpression DealParame(CRLExpression.CRLExpression par1, string typeStr, out string typeStr2) { var par = par1.Data + ""; typeStr2 = typeStr; //todo 非关系型数据库不参数化 if (dbContext.DataBaseArchitecture == DataBaseArchitecture.NotRelation) { return(par1); } if (par1.Data is CRLExpression.MethodCallObj) { var method = par1.Data as CRLExpression.MethodCallObj; var _DBAdapter = DBAdapter.DBAdapterBase.GetDBAdapterBase(dbContext); var dic = MethodAnalyze.GetMethos(_DBAdapter); if (!dic.ContainsKey(method.MethodName)) { throw new CRLException("LambdaQuery不支持方法" + method.MethodName); } int newParIndex = parIndex; par = dic[method.MethodName](method, ref newParIndex, AddParame); parIndex = newParIndex; } //字段会返回替换符 bool needPar = par1.Type == CRLExpression.CRLExpressionType.Value;//是否需要参数化处理 if (!needPar) { par1.Data = par; return(par1); } if (needPar) { if (par.ToUpper() == "NULL") { typeStr2 = ""; if (typeStr == "=") { par = " IS NULL "; } else if (typeStr == "<>") { par = " IS NOT NULL "; } } else { QueryParames.Add("par" + parIndex, par); par = "@par" + parIndex; parIndex += 1; } } par1.Data = par; return(par1); }
Expression CreateLambdaBinary(CRLExpression expression) { var left = expression.Left; var right = expression.Right; Expression exp; object value; var type = expression.ExpType; if (left.Type == CRLExpressionType.MethodCall)//按方法运算 如 b.NameSubstring,Indexof(0,1)=="123" { //按属性的子方法 exp = CreateLambdaMethodCall2(left); value = ObjectConvert.ConvertObject(exp.Type, right.Data); } else if (left.Type == CRLExpressionType.Tree) { exp = CreateLambdaBinary(left);//todo 暂时在左边 value = right.Data; //throw new CRLException("不支持的运算 "+ left.ExpressionType); } else//按属性运算 如b.Id==1 { exp = creater.CreatePropertyExpression(left.Data.ToString()); value = right.Data; } switch (type) { case ExpressionType.Equal: return(creater.Equal(exp, value)); case ExpressionType.NotEqual: return(creater.NotEqual(exp, value)); case ExpressionType.GreaterThan: return(creater.Greater(exp, value)); case ExpressionType.LessThan: return(creater.Less(exp, value)); case ExpressionType.GreaterThanOrEqual: return(creater.GreaterThan(exp, value)); case ExpressionType.LessThanOrEqual: return(creater.LessThan(exp, value)); case ExpressionType.And: return(creater.And(exp, value)); case ExpressionType.Or: return(creater.Or(exp, value)); default: throw new CRLException("没有对应的运算方法 " + type); } }
FilterData BinaryCRLExpression(CRLExpression.CRLExpression left, CRLExpression.CRLExpression right, ExpressionType expressionType) { var parLeft = RouteCRLExpression(left); var parRight = RouteCRLExpression(right); return(new FilterData() { Filter = getFilter(parLeft, parRight, expressionType) }); }
Expression <Func <T, bool> > CreateLambdaMethodCall(CRLExpression expression) { //表示方法调用 var arry = expression.Data.ToString().Split('|'); var propertyName = arry[0]; var methodName = arry[1]; var args = expression.Data.ToString().Substring(propertyName.Length + methodName.Length + 2); var value = args.Split(','); if (args == "") { value = new string[] { }; } //if (CreateLambdaMethodCallCache.Count == 0) //{ // CreateLambdaMethodCallCache.Add("Contains", creater.Contains); // CreateLambdaMethodCallCache.Add("StartsWith", creater.StartsWith); // CreateLambdaMethodCallCache.Add("EndsWith", creater.EndsWith); // CreateLambdaMethodCallCache.Add("IsNullOrEmpty", creater.EndsWith); //} MethodHandler method; switch (methodName) { case "Contains": method = creater.Contains; break; case "StartsWith": method = creater.StartsWith; break; case "EndsWith": method = creater.EndsWith; break; case "IsNullOrEmpty": method = creater.IsNullOrEmpty; break; case "Equals": method = creater.Equals; break; default: throw new CRLException("没有对应的方法 " + methodName); } //var a = CreateLambdaMethodCallCache.TryGetValue(methodName, out method); ////todo 更多方法解析 //if (!a) //{ // throw new CRLException("没有对应的方法 " + methodName); //} return(method(propertyName, value)); }
/// <summary> /// 解析表达式 /// </summary> /// <param name="exp"></param> /// <param name="nodeType"></param> /// <param name="firstLevel">是否首次调用,来用修正bool一元运算</param> /// <returns></returns> public CRLExpression.CRLExpression RouteExpressionHandler(Expression exp, ExpressionType?nodeType = null, bool firstLevel = false) { if (exp is BinaryExpression) { //like a.Name??str BinaryExpression be = (BinaryExpression)exp; if (be.NodeType == ExpressionType.Coalesce) { var par1 = new CRLExpression.CRLExpression(); par1.Type = CRLExpression.CRLExpressionType.MethodCall; var member = be.Left as MemberExpression; if (member == null) { throw new Exception(be.Left + "不为MemberExpression"); } var args = RouteExpressionHandler(be.Right); par1.Data = new CRLExpression.MethodCallObj() { MemberName = member.Member.Name, MethodName = "IsNull", Args = new List <object>() { args.Data }, MemberQueryName = member.Member.Name }; return(DealParame(par1, "")); } return(BinaryExpressionHandler(be.Left, be.Right, be.NodeType)); } if (exp is MemberExpression) { return(MemberExpressionHandler(exp, nodeType, firstLevel)); } else if (exp is ConstantExpression) { return(ConstantExpressionHandler(exp, nodeType, firstLevel)); } else if (exp is MethodCallExpression) { return(MethodCallExpressionHandler(exp, nodeType, firstLevel)); } else if (exp is UnaryExpression) { return(UnaryExpressionHandler(exp, nodeType, firstLevel)); } else if (exp is NewArrayExpression) { return(NewArrayExpressionHandler(exp, nodeType, firstLevel)); } else { throw new Exception("不支持此语法解析:" + exp); } }
CRLExpression BinaryExpressionHandler(Expression left, Expression right, ExpressionType type, int level = 1) { var types = new ExpressionType[] { ExpressionType.Equal, ExpressionType.GreaterThan, ExpressionType.GreaterThanOrEqual, ExpressionType.LessThan, ExpressionType.LessThanOrEqual, ExpressionType.NotEqual }; var leftPar = RouteExpressionHandler(left); var isBinary = types.Contains(type); var rightPar = RouteExpressionHandler(right); var e = new CRLExpression() { ExpType = type, Left = leftPar, Right = rightPar, Type = isBinary ? CRLExpressionType.Binary : CRLExpressionType.Tree }; return(e); }
Expression <Func <T, bool> > CreateLambdaTree(CRLExpression expression) { var expression1 = CreateLambda(expression.Left); var expression2 = CreateLambda(expression.Right); if (expression.ExpressionType == "AndAlso") { return(expression1.Compose(expression2, Expression.AndAlso)); } else { return(expression1.Compose(expression2, Expression.OrElse)); } return(null); }
CRLExpression.CRLExpression DealParame(CRLExpression.CRLExpression par1, string typeStr) { var par = par1.Data + ""; //typeStr2 = typeStr; //todo 非关系型数据库不参数化 if (dbContext.DataBaseArchitecture == DataBaseArchitecture.NotRelation) { return(par1); } if (parIndex > 1000) { throw new CRLException("参数计数超过了1000,请确认数据访问对象没有被静态化"); } switch (par1.Type) { case CRLExpression.CRLExpressionType.Value: #region value if (par1.Data == null) { par = __DBAdapter.IsNotFormat(typeStr != "=") + "null"; } else { QueryParames.Add("par" + parIndex, par); par = "@par" + parIndex; parIndex += 1; } #endregion break; case CRLExpression.CRLExpressionType.MethodCall: #region method var method = par1.Data as CRLExpression.MethodCallObj; var dic = MethodAnalyze.GetMethos(__DBAdapter); if (!dic.ContainsKey(method.MethodName)) { throw new CRLException("LambdaQuery不支持扩展方法" + method.MemberQueryName + "." + method.MethodName); } int newParIndex = parIndex; par = dic[method.MethodName](method, ref newParIndex, AddParame); parIndex = newParIndex; #endregion break; } par1.DataParamed = par; return(par1); }
CRLExpression.CRLExpression BinaryExpressionHandler(Expression left, Expression right, ExpressionType type) { StringBuilder sb = new StringBuilder(); sb.Append("("); var leftPar = RouteExpressionHandler(left); string typeStr = ExpressionTypeCast(type); var rightPar = RouteExpressionHandler(right); #region 修正bool值一元运算 //t1.isTop=1 if (leftPar.Type == CRLExpression.CRLExpressionType.Binary && rightPar.Type == CRLExpression.CRLExpressionType.Name) { var proType = ((MemberExpression)right).Type; if (proType == typeof(bool)) { rightPar.Data = rightPar.Data + "=1"; } } else if (rightPar.Type == CRLExpression.CRLExpressionType.Binary && leftPar.Type == CRLExpression.CRLExpressionType.Name) { var proType = ((MemberExpression)left).Type; if (proType == typeof(bool)) { leftPar.Data = leftPar.Data + "=1"; } } #endregion string typeStr2; leftPar = DealParame(leftPar, typeStr, out typeStr2); sb.Append(leftPar.Data); rightPar = DealParame(rightPar, typeStr, out typeStr2); sb.Append(typeStr2); sb.Append(rightPar.Data); sb.Append(")"); //return sb.ToString(); var types = new ExpressionType[] { ExpressionType.Equal, ExpressionType.GreaterThan, ExpressionType.GreaterThanOrEqual, ExpressionType.LessThan, ExpressionType.LessThanOrEqual, ExpressionType.NotEqual }; var isBinary = types.Contains(type); var e = new CRLExpression.CRLExpression() { ExpressionType = type.ToString(), Left = leftPar, Right = rightPar, Type = isBinary ? CRLExpression.CRLExpressionType.Binary : CRLExpression.CRLExpressionType.Tree }; e.SqlOut = sb.ToString(); e.Data = e.SqlOut; return(e); }
/// <summary> /// 转换为Lambda表达式 /// </summary> /// <param name="expression"></param> /// <returns></returns> public Expression <Func <T, bool> > CreateLambda(CRLExpression expression) { if (expression.Type == CRLExpressionType.Tree) { //解析一个表达式树 return(CreateLambdaTree(expression)); } else if (expression.Type == CRLExpressionType.MethodCall) { //方法 return(CreateLambdaMethodCall(expression)); } else { //二元运算 return(CreateLambdaBinary(expression) as Expression <Func <T, bool> >); } }
public string DealCRLExpression(Expression exp, CRLExpression.CRLExpression b, string typeStr, out bool isNullValue, bool first = false) { isNullValue = false; switch (b.Type) { case CRLExpression.CRLExpressionType.Name: return(FormatFieldPrefix(b.MemberType, b.Data.ToString())); case CRLExpression.CRLExpressionType.Binary: return(b.Data.ToString()); default: var valExp = (b.IsConstantValue || first) ? b : RouteExpressionHandler(exp); isNullValue = valExp.Data == null; var par2 = DealParame(valExp, typeStr); return(par2.DataParamed); } }
internal MethodCallExpression CreateLambdaMethodCall2(CRLExpression expression) { //表示二元运算的方法 var creater = new LambdaCreater <T>(); var arry = expression.Data.ToString().Split('|'); var propertyName = arry[0]; var methodName = arry[1]; var args = expression.Data.ToString().Substring(propertyName.Length + methodName.Length + 2); var dic = new Dictionary <string, MethodResultHandler>(); dic.Add("Substring", creater.Substring); dic.Add("IndexOf", creater.IndexOf); if (!dic.ContainsKey(methodName)) { throw new CRLException("没有对应的方法 " + methodName); } return(dic[methodName](propertyName, args.Split(','))); }
Expression <Func <T, bool> > CreateLambdaMethodCall(CRLExpression expression) { //表示方法调用 var creater = new LambdaCreater <T>(); var arry = expression.Data.ToString().Split('|'); var propertyName = arry[0]; var methodName = arry[1]; var args = expression.Data.ToString().Substring(propertyName.Length + methodName.Length + 2); var dic = new Dictionary <string, MethodHandler>(); dic.Add("Contains", creater.Contains); dic.Add("StartsWith", creater.StartsWith); dic.Add("EndsWith", creater.EndsWith); //todo 更多方法解析 if (!dic.ContainsKey(methodName)) { throw new CRLException("没有对应的方法 " + methodName); } return(dic[methodName](propertyName, args.Split(','))); }
internal MethodCallExpression CreateLambdaMethodCall2(CRLExpression expression) { //表示二元运算的方法 var arry = expression.Data.ToString().Split('|'); var propertyName = arry[0]; var methodName = arry[1]; var args = expression.Data.ToString().Substring(propertyName.Length + methodName.Length + 2); string[] value = args.Split(','); if (args == "") { value = new string[] { }; } MethodResultHandler method; switch (methodName) { case "Substring": method = creater.Substring; break; case "IndexOf": method = creater.IndexOf; break; case "ToString": method = creater.ToString; break; case "ToInt32": method = creater.ToInt32; break; case "ToDecimal": method = creater.ToDecimal; break; case "ToDouble": method = creater.ToDouble; break; case "ToBoolean": method = creater.ToBoolean; break; case "ToDateTime": method = creater.ToDateTime; break; case "ToInt16": method = creater.ToInt16; break; case "ToSingle": method = creater.ToSingle; break; case "ToLower": method = creater.ToLower; break; case "ToUpper": method = creater.ToUpper; break; default: throw new CRLException("没有对应的方法 " + methodName); } return(method(propertyName, value)); }
CRLExpression.CRLExpression BinaryExpressionHandler(Expression left, Expression right, ExpressionType expType) { var isBinary = binaryTypes.Contains(expType); //string key = ""; string typeStr = ExpressionTypeCast(expType); string __typeStr2 = typeStr; string outLeft, outRight; bool isNullValue = false; //isBinary = false; if (isBinary) { #region 二元运算缓存 并没有效率提升 //if (SettingConfig.UseLambdaCache&&false) //{ // CRLExpression.CRLExpression cacheItem; // key = string.Format("{0}{1}{2}{3}", __PrefixsAllKey, left, expType, right); // var a = BinaryExpressionCache.TryGetValue(key, out cacheItem); // if (a) // { // outLeft = DealCRLExpression(left, cacheItem.Left, typeStr, out isNullValue); // outRight = DealCRLExpression(right, cacheItem.Right, typeStr, out isNullValue); // if (isNullValue)//left为null则语法错误 // { // __typeStr2 = ""; // } // cacheItem.SqlOut = string.Format("({0}{1}{2})", outLeft, __typeStr2, outRight); // cacheItem.Data = cacheItem.SqlOut; // return cacheItem; // } //} #endregion } var sb = ""; var leftPar = RouteExpressionHandler(left); var rightPar = RouteExpressionHandler(right); #region 修正bool值一元运算 //b => b.IsTop && b.Id < 10 if (expType == ExpressionType.AndAlso || expType == ExpressionType.OrElse) { if (leftPar.Type == CRLExpression.CRLExpressionType.Name) { left = left.Equal(Expression.Constant(true)); leftPar = RouteExpressionHandler(left); } else if (rightPar.Type == CRLExpression.CRLExpressionType.Name) { right = right.Equal(Expression.Constant(true)); rightPar = RouteExpressionHandler(right); } } #endregion outLeft = DealCRLExpression(left, leftPar, typeStr, out isNullValue, true); outRight = DealCRLExpression(right, rightPar, typeStr, out isNullValue, true); if (isNullValue)//left为null则语法错误 { __typeStr2 = ""; } sb = string.Format("({0}{1}{2})", outLeft, __typeStr2, outRight); var e = new CRLExpression.CRLExpression() { ExpType = expType, Left = leftPar, Right = rightPar, Type = isBinary ? CRLExpression.CRLExpressionType.Binary : CRLExpression.CRLExpressionType.Tree }; e.SqlOut = sb; e.Data = e.SqlOut; //if (isBinary && SettingConfig.UseLambdaCache && false) //{ // BinaryExpressionCache[key] = e; //} return(e); }
CRLExpression.CRLExpression MemberExpressionHandler(Expression exp, ExpressionType?nodeType = null, bool firstLevel = false) { #region MemberExpression //区分 属性表达带替换符{0} 变量值不带 MemberExpression mExp = (MemberExpression)exp; if (mExp.Expression != null && mExp.Expression.NodeType == ExpressionType.Parameter) //like b.Name==b.Name1 或b.Name { #region MemberParameter var fieldName = mExp.Member.Name; var type = mExp.Expression.Type; if (mExp.Member.ReflectedType.Name.StartsWith("<>f__AnonymousType"))//按匿名类 { //var queryField = FormatFieldPrefix(type, fieldName); var exp2 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Name, Data = fieldName, MemberType = type }; //MemberExpressionCache[key] = exp2; return(exp2); } CRL.Attribute.FieldAttribute field; var a = TypeCache.GetProperties(type, true).TryGetValue(fieldName, out field); if (!a) { throw new CRLException("类型 " + type.Name + "." + fieldName + " 未设置Mapping,请检查查询条件"); } //if (!string.IsNullOrEmpty(field.VirtualField))//按虚拟字段 //{ // //return filed.VirtualField; // var queryField = field.VirtualField.Replace("{" + type.FullName + "}", Prefixs[type]);//替换前辍 // var exp2 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Name, Data = queryField, MemberType = type }; // //MemberExpressionCache[key] = exp2; // return exp2; //} //var fieldStr = FormatFieldPrefix(type, field.MapingName);//格式化为别名 //return field; if (firstLevel) { var exp2 = exp.Equal(Expression.Constant(true)); return(RouteExpressionHandler(exp2)); } if (field.DefaultCRLExpression != null) { var c2 = field.DefaultCRLExpression; c2.Data = __DBAdapter.FieldNameFormat(field); return(c2); } var fieldStr = __DBAdapter.FieldNameFormat(field); var exp3 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Name, Data = fieldStr, MemberType = type }; field.DefaultCRLExpression = exp3; return(exp3); #endregion } else { //string key = mExp.ToString() + firstLevel; //CRLExpression.CRLExpression val; //var a1 = MemberExpressionCache.TryGetValue(key, out val); //if (a1) //{ // return val; //} #region 值 bool isConstant; var obj = GetParameExpressionValue(mExp, out isConstant); if (obj is Enum) { obj = (int)obj; } else if (obj is Boolean)//sql2000需要转换 { obj = Convert.ToInt32(obj); } var exp4 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Value, Data = obj, IsConstantValue = isConstant }; //if (isConstant) //{ // MemberExpressionCache[key] = exp4; //} return(exp4); #endregion } #endregion }
CRLExpression.CRLExpression DealParame(CRLExpression.CRLExpression par1, string typeStr) { var par = par1.Data + ""; //typeStr2 = typeStr; //todo 非关系型数据库不参数化 if (dbContext.DataBaseArchitecture == DataBaseArchitecture.NotRelation) { return(par1); } var a = parameDicList.TryGetValue(__DBAdapter.DBType, out string[] parameDic); if (!a) { parameDic = new string[5000]; for (int i = 0; i < 5000; i++) { parameDic[i] = __DBAdapter.GetParamName("p", i); } parameDicList.TryAdd(__DBAdapter.DBType, parameDic); } if (parIndex >= 5000) { //MSSQL 参数最多2800 throw new Exception("参数计数超过了5000,请确认数据访问对象没有被静态化" + parIndex); } switch (par1.Type) { case CRLExpression.CRLExpressionType.Value: #region value if (par1.Data == null) { par = __DBAdapter.IsNotFormat(typeStr != "=") + "null"; } else { if (SettingConfig.FieldParameName) { par1.DataParamed = par; return(par1); //参数名按字段名 } var _par = parameDic[parIndex]; AddParame(_par, par); par = _par; parIndex += 1; } #endregion break; case CRLExpression.CRLExpressionType.MethodCall: #region method var method = par1.Data as CRLExpression.MethodCallObj; #region in优化 MSSQL内部已自动优化 var nodeType = method.ExpressionType; /** * if (dbContext.DataBaseArchitecture == DataBaseArchitecture.Relation && method.MethodName == "In" && lambdaQueryBase.__AutoInJoin > 5 && nodeType == ExpressionType.Equal) * { * var inArgs = method.Args[0] as System.Collections.IEnumerable; * int _i = 0; * Type innerType = null; * var pars = new List<InJoin>(); * var batchNo = System.Guid.NewGuid().ToString().Replace("-", ""); * foreach (var a in inArgs) * { * _i += 1; * if (innerType == null) * { * innerType = a.GetType(); * } * var obj2 = new InJoin() { BatchNo = batchNo, V_String = "" }; * obj2.SetValue(innerType, a); * pars.Add(obj2); * } * if (_i > lambdaQueryBase.__AutoInJoin) * { * QueryParames.Add("__batchNO", batchNo); * var typeJoin = typeof(InJoin); * var inJoinName = lambdaQueryBase.GetPrefix(typeJoin); * var joinFormat = string.Format("{1}BatchNo=@__batchNO and {0}={1}V_{2}", method.MemberQueryName, inJoinName, innerType.Name); * lambdaQueryBase.AddInnerRelation(new TypeQuery(typeJoin), JoinType.Inner, joinFormat); * par1.DataParamed = ""; * var dbEx = DBExtendFactory.CreateDBExtend(dbContext); * dbEx.CheckTableCreated(typeJoin); * __DBAdapter.BatchInsert(pars); * lambdaQueryBase.__RemoveInJionBatchNo = batchNo; * return par1; * } * } */ #endregion var dic = MethodAnalyze.GetMethos(__DBAdapter); if (!dic.ContainsKey(method.MethodName)) { throw new Exception("LambdaQuery不支持扩展方法" + method.MemberQueryName + "." + method.MethodName); } int newParIndex = parIndex; par = dic[method.MethodName](method, ref newParIndex, AddParame); parIndex = newParIndex; #endregion break; } par1.DataParamed = par; return(par1); }
CRLExpression.CRLExpression MethodCallExpressionHandler(Expression exp, ExpressionType?nodeType = null, bool firstLevel = false) { #region methodCall MethodCallExpression mcExp = (MethodCallExpression)exp; var arguments = new List <object>(); var allArguments = new List <Expression>(mcExp.Arguments); int argsIndex = 0; Expression firstArgs; bool isLambdaQueryJoinExt = false; if (mcExp.Object == null) //区分静态方法还是实例方法 { firstArgs = allArguments[0]; //like b.Name.IsNull("22") argsIndex = 1; if (firstArgs.Type.Name.Contains("LambdaQueryJoin")) { isLambdaQueryJoinExt = true; } } else { firstArgs = mcExp.Object; //like b.Id.ToString() if (allArguments.Count > 0 && (allArguments[0] is MemberExpression)) //like ids.Contains(b.Id) { var mexp2 = allArguments[0] as MemberExpression; var firstArgsM = firstArgs as MemberExpression; //var par2 = (ParameterExpression)mexp2.Expression; if (mexp2.Expression is ParameterExpression && firstArgsM.Expression is ConstantExpression) { firstArgs = allArguments[0]; argsIndex = 1; allArguments.Add(mcExp.Object); if (firstArgs.Type.Name.Contains("LambdaQueryJoin")) { isLambdaQueryJoinExt = true; } } } } #region MethodCallExpression //bool isConstantMethod = false; MemberExpression memberExpression; string methodField = ""; string memberName = ""; string methodName = mcExp.Method.Name; if (firstArgs is ParameterExpression || isLambdaQueryJoinExt) { var exp2 = mcExp.Arguments[1] as UnaryExpression; var type = exp2.Operand.GetType(); var p = type.GetProperty("Body"); var exp3 = p.GetValue(exp2.Operand, null) as Expression; methodField = RouteExpressionHandler(exp3).SqlOut; memberName = ""; } else if (firstArgs is UnaryExpression)//like a.Code.Count() { memberExpression = (firstArgs as UnaryExpression).Operand as MemberExpression; memberName = memberExpression.Member.Name; var field = TypeCache.GetProperties(memberExpression.Expression.Type, true)[memberName]; memberName = __DBAdapter.FieldNameFormat(field); methodField = FormatFieldPrefix(memberExpression.Expression.Type, memberName); } else if (firstArgs is BinaryExpression) { var be = firstArgs as BinaryExpression; methodField = BinaryExpressionHandler(be.Left, be.Right, be.NodeType).Data.ToString(); } else if (firstArgs is MemberExpression) { //like a.Code memberExpression = firstArgs as MemberExpression; memberName = memberExpression.Member.Name; var type = memberExpression.Expression.Type; if (type.IsSubclassOf(typeof(IModel))) { var field = TypeCache.GetProperties(type, true)[memberExpression.Member.Name]; memberName = __DBAdapter.FieldNameFormat(field); } if (memberExpression.Expression.NodeType == ExpressionType.Parameter) { methodField = FormatFieldPrefix(memberExpression.Expression.Type, memberName); //var allConstant = true; for (int i = argsIndex; i < allArguments.Count; i++) { bool isConstant2; var obj = GetParameExpressionValue(allArguments[i], out isConstant2); arguments.Add(obj); } } else { //like Convert.ToDateTime(times) var obj = ConstantValueVisitor.GetParameExpressionValue(firstArgs); arguments.Add(obj); for (int i = argsIndex; i < allArguments.Count; i++) { bool isConstant2; var obj2 = GetParameExpressionValue(allArguments[i], out isConstant2); arguments.Add(obj2); } } } else if (firstArgs is ConstantExpression)//按常量 { //like DateTime.Parse("2016-02-11 12:56"), //isConstantMethod = true; var obj = ConstantValueVisitor.GetParameExpressionValue(firstArgs); arguments.Add(obj); } //else //{ // throw new CRLException("不支持此语法解析:" + args); //} if (nodeType == null) { nodeType = ExpressionType.Equal; } if (string.IsNullOrEmpty(methodField)) { //当是常量转换方法 var method = mcExp.Method; object obj = null; if (method.IsStatic) //like DateTime.Parse("2016-02-11") { if (method.IsGenericMethod) //扩展方法,like public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value) { var valueObj = (ExpressionValueObj)arguments[1]; if (valueObj == null) { throw new Exception("不支持此语法:" + mcExp); } memberName = valueObj.member.Name; arguments = new List <object>() { arguments[0] }; methodField = valueObj.Value.ToString(); goto lable1; } else { obj = method.Invoke(null, arguments.ToArray()); } } else//like time.AddDays(1) { if (arguments.Count == 0) { throw new Exception("未能解析" + exp); } var args1 = arguments.First(); arguments.RemoveAt(0); if (arguments.Count > 0) { if (arguments[0] is ExpressionValueObj) { throw new Exception("不支持这样的语法:" + exp); } } obj = method.Invoke(args1, arguments.ToArray()); } var exp2 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Value, Data = obj }; return(exp2); } lable1: var methodInfo = new CRLExpression.MethodCallObj() { Args = arguments, ExpressionType = nodeType.Value, MemberName = memberName, MethodName = methodName, MemberQueryName = methodField }; methodInfo.ReturnType = mcExp.Type; #endregion var exp4 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.MethodCall, Data = methodInfo }; return(exp4); #endregion }
CRLExpression.CRLExpression BinaryExpressionHandler(Expression left, Expression right, ExpressionType expType) { var isBinary = binaryTypes.Contains(expType); //string key = ""; string typeStr = ExpressionTypeCast(expType); string __typeStr2 = typeStr; string outLeft, outRight; bool isNullValue = false; //isBinary = false; if (isBinary) { } var sb = ""; var leftPar = RouteExpressionHandler(left); var rightPar = RouteExpressionHandler(right); #region 修正bool值一元运算 //b => b.IsTop && b.Id < 10 if (expType == ExpressionType.AndAlso || expType == ExpressionType.OrElse) { if (leftPar.Type == CRLExpression.CRLExpressionType.Name) { left = left.Equal(Expression.Constant(true)); leftPar = RouteExpressionHandler(left); } else if (rightPar.Type == CRLExpression.CRLExpressionType.Name) { right = right.Equal(Expression.Constant(true)); rightPar = RouteExpressionHandler(right); } } #endregion outLeft = DealCRLExpression(left, leftPar, typeStr, out isNullValue, true); outRight = DealCRLExpression(right, rightPar, typeStr, out isNullValue, true); #region 固定名称的参数 if (isBinary && SettingConfig.FieldParameName) { if ((int)(leftPar.Type | rightPar.Type) == 12) { CRLExpression.CRLExpression tempName; CRLExpression.CRLExpression tempValue; if (leftPar.Type == CRLExpression.CRLExpressionType.Name) { tempName = leftPar; tempValue = rightPar; } else { tempName = rightPar; tempValue = leftPar; outLeft = outRight; } existsTempParameName = existsTempParameName ?? new List <string>(); var pre = Prefixs[tempName.MemberType]; pre = pre.Replace(".", $"_"); var pName = __DBAdapter.GetParamName(pre, tempName.Data_); if (existsTempParameName.Contains(pName)) { pName = pName.Replace("_", "_" + existsTempParameName.Count + "_"); } AddParame(pName, tempValue.Data); existsTempParameName.Add(pName); outRight = pName; } } #endregion if (isNullValue)//left为null则语法错误 { __typeStr2 = ""; } if (isBinary) { sb = string.Format("({0}{1}{2})", outLeft, __typeStr2, outRight); } else { sb = string.Format("{0}{1}{2}", outLeft, __typeStr2, outRight); } var e = new CRLExpression.CRLExpression() { ExpType = expType, Left = leftPar, Right = rightPar, Type = isBinary ? CRLExpression.CRLExpressionType.Binary : CRLExpression.CRLExpressionType.Tree }; e.SqlOut = sb; e.Data = e.SqlOut; return(e); }
CRLExpression.CRLExpression MethodCallExpressionHandler(Expression exp, ExpressionType?nodeType = null, bool firstLevel = false) { #region methodCall MethodCallExpression mcExp = (MethodCallExpression)exp; var arguments = new List <object>(); var allArguments = mcExp.Arguments; int argsIndex = 0; Expression firstArgs; bool isLambdaQueryJoinExt = false; if (mcExp.Method.IsStatic) //区分静态方法还是实例方法 { firstArgs = allArguments[0]; //like b.Name.IsNull("22") argsIndex = 1; if (firstArgs.Type.Name.Contains("LambdaQueryJoin")) { isLambdaQueryJoinExt = true; } } else { firstArgs = mcExp.Object;//like b.Id.ToString() } #region 缓存处理 效率并不高 //MethodCallExpressionCacheItem methodCache; //string key = ""; //if (SettingConfig.UseLambdaCache&& false) //{ // key = __PrefixsAllKey + mcExp + nodeType; // var exists = MethodCallExpressionCache.TryGetValue(key, out methodCache); // if (exists) // { // if (!methodCache.isConstantMethod) // { // var methodCall = methodCache.CRLExpression.Data as CRLExpression.MethodCallObj; // if (methodCall.Args.Count > 0) // { // for (int i = argsIndex; i < allArguments.Count; i++) // { // bool isConstant1; // var obj = GetParameExpressionValue(allArguments[i], out isConstant1); // arguments.Add(obj); // } // methodCall.Args = arguments; // } // } // methodCache.CRLExpression.SqlOut = ""; // return methodCache.CRLExpression; // } //} #endregion #region MethodCallExpression //bool isConstantMethod = false; MemberExpression memberExpression; string methodField = ""; string memberName = ""; string methodName = mcExp.Method.Name; if (firstArgs is ParameterExpression || isLambdaQueryJoinExt) { var exp2 = mcExp.Arguments[1] as UnaryExpression; var type = exp2.Operand.GetType(); var p = type.GetProperty("Body"); var exp3 = p.GetValue(exp2.Operand, null) as Expression; methodField = RouteExpressionHandler(exp3).SqlOut; memberName = ""; } else if (firstArgs is UnaryExpression)//like a.Code.Count() { memberExpression = (firstArgs as UnaryExpression).Operand as MemberExpression; memberName = memberExpression.Member.Name; var field = TypeCache.GetProperties(memberExpression.Expression.Type, true)[memberName]; memberName = __DBAdapter.FieldNameFormat(field); methodField = FormatFieldPrefix(memberExpression.Expression.Type, memberName); } else if (firstArgs is BinaryExpression) { var be = firstArgs as BinaryExpression; methodField = BinaryExpressionHandler(be.Left, be.Right, be.NodeType).Data.ToString(); } else if (firstArgs is MemberExpression) { //like a.Code memberExpression = firstArgs as MemberExpression; memberName = memberExpression.Member.Name; var type = memberExpression.Expression.Type; if (type.IsSubclassOf(typeof(IModel))) { var field = TypeCache.GetProperties(type, true)[memberExpression.Member.Name]; memberName = __DBAdapter.FieldNameFormat(field); } if (memberExpression.Expression.NodeType == ExpressionType.Parameter) { methodField = FormatFieldPrefix(memberExpression.Expression.Type, memberName); //var allConstant = true; for (int i = argsIndex; i < allArguments.Count; i++) { bool isConstant2; var obj = GetParameExpressionValue(allArguments[i], out isConstant2); arguments.Add(obj); } } else { //like Convert.ToDateTime(times) var obj = ConstantValueVisitor.GetParameExpressionValue(firstArgs); arguments.Add(obj); for (int i = argsIndex; i < allArguments.Count; i++) { bool isConstant2; var obj2 = GetParameExpressionValue(allArguments[i], out isConstant2); arguments.Add(obj2); } } } else if (firstArgs is ConstantExpression)//按常量 { //like DateTime.Parse("2016-02-11 12:56"), //isConstantMethod = true; var obj = ConstantValueVisitor.GetParameExpressionValue(firstArgs); arguments.Add(obj); } //else //{ // throw new CRLException("不支持此语法解析:" + args); //} if (nodeType == null) { nodeType = ExpressionType.Equal; } if (string.IsNullOrEmpty(methodField)) { //当是常量转换方法 var method = mcExp.Method; object obj; if (mcExp.Method.IsStatic)//like DateTime.Parse("2016-02-11") { obj = method.Invoke(null, arguments.ToArray()); } else//like time.AddDays(1) { if (arguments.Count == 0) { throw new Exception("未能解析" + exp); } var args1 = arguments.First(); arguments.RemoveAt(0); obj = method.Invoke(args1, arguments.ToArray()); } var exp2 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Value, Data = obj }; //var cache = new MethodCallExpressionCacheItem() { CRLExpression = exp2, argsIndex = argsIndex, isConstantMethod = isConstantMethod, isStatic = mcExp.Method.IsStatic }; //MethodCallExpressionCache[key] = cache; return(exp2); } var methodInfo = new CRLExpression.MethodCallObj() { Args = arguments, ExpressionType = nodeType.Value, MemberName = memberName, MethodName = methodName, MemberQueryName = methodField }; methodInfo.ReturnType = mcExp.Type; #endregion var exp4 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.MethodCall, Data = methodInfo }; //if (SettingConfig.UseLambdaCache && false) //{ // var cache2 = new MethodCallExpressionCacheItem() { CRLExpression = exp4, argsIndex = argsIndex, isConstantMethod = isConstantMethod }; // MethodCallExpressionCache[key] = cache2; //} return(exp4); #endregion }
CRLExpression.CRLExpression MemberExpressionHandler(Expression exp, ExpressionType?nodeType = null, bool firstLevel = false) { #region MemberExpression //区分 属性表达带替换符{0} 变量值不带 MemberExpression mExp = (MemberExpression)exp; if (mExp.Expression != null && mExp.Expression.NodeType == ExpressionType.Parameter) //like b.Name==b.Name1 或b.Name { #region MemberParameter var memberName = mExp.Member.Name; var type = mExp.Expression.Type; if (mExp.Member.ReflectedType.Name.StartsWith("<>f__AnonymousType"))//按匿名类 { var exp2 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Name, Data = memberName, MemberType = type }; return(exp2); } if (firstLevel)//没有运算符的BOOL判断 { var exp2 = exp.Equal(Expression.Constant(true)); return(RouteExpressionHandler(exp2)); } CRL.Attribute.FieldInnerAttribute field; var a = TypeCache.GetProperties(type, true).TryGetValue(memberName, out field); if (!a) { throw new Exception("类型 " + type.Name + "." + memberName + " 未设置Mapping,请检查查询条件"); } if (field.DefaultCRLExpression != null) { var c2 = field.DefaultCRLExpression; c2.Data = __DBAdapter.FieldNameFormat(field); return(c2); } var fieldStr = __DBAdapter.FieldNameFormat(field); var exp3 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Name, Data = fieldStr, Data_ = field.MapingName, MemberType = type }; field.DefaultCRLExpression = exp3; return(exp3); #endregion } else { #region 值 bool isConstant; var obj = GetParameExpressionValue(mExp, out isConstant); if (obj is Enum) { obj = (int)obj; } else if (obj is Boolean)//sql2000需要转换 { obj = Convert.ToInt32(obj); } var exp4 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Value, Data = obj, IsConstantValue = isConstant }; //if (isConstant) //{ // MemberExpressionCache[key] = exp4; //} return(exp4); #endregion } #endregion }
CRLExpression.CRLExpression BinaryExpressionHandler(Expression left, Expression right, ExpressionType expType) { var isBinary = binaryTypes.Contains(expType); string key = ""; string typeStr = ExpressionTypeCast(expType); string __typeStr2 = typeStr; string outLeft, outRight; bool isNullValue = false; //isBinary = false; if (isBinary) { #region 二元运算缓存 CRLExpression.CRLExpression cacheItem; key = string.Format("{0}{1}{2}{3}", __PrefixsAllKey, left, expType, right); var a = BinaryExpressionCache.TryGetValue(key, out cacheItem); if (a) { outLeft = DealCRLExpression(left, cacheItem.Left, typeStr, out isNullValue); outRight = DealCRLExpression(right, cacheItem.Right, typeStr, out isNullValue); if (isNullValue)//left为null则语法错误 { __typeStr2 = ""; } cacheItem.SqlOut = string.Format("({0}{1}{2})", outLeft, __typeStr2, outRight); cacheItem.Data = cacheItem.SqlOut; return(cacheItem); } #endregion } StringBuilder sb = new StringBuilder(); var leftPar = RouteExpressionHandler(left); var rightPar = RouteExpressionHandler(right); #region 修正bool值一元运算 //b => b.IsTop && b.Id < 10 if (expType == ExpressionType.AndAlso || expType == ExpressionType.OrElse) { if (leftPar.Type == CRLExpression.CRLExpressionType.Name) { left = left.Equal(Expression.Constant(true)); leftPar = RouteExpressionHandler(left); } else if (rightPar.Type == CRLExpression.CRLExpressionType.Name) { right = right.Equal(Expression.Constant(true)); rightPar = RouteExpressionHandler(right); } } #endregion outLeft = DealCRLExpression(left, leftPar, typeStr, out isNullValue, true); outRight = DealCRLExpression(right, rightPar, typeStr, out isNullValue, true); if (isNullValue)//left为null则语法错误 { __typeStr2 = ""; } sb.AppendFormat("({0}{1}{2})", outLeft, __typeStr2, outRight); var e = new CRLExpression.CRLExpression() { ExpType = expType.ToString(), Left = leftPar, Right = rightPar, Type = isBinary ? CRLExpression.CRLExpressionType.Binary : CRLExpression.CRLExpressionType.Tree }; e.SqlOut = sb.ToString(); e.Data = e.SqlOut; if (isBinary) { BinaryExpressionCache[key] = e; } return(e); }