public static IDbQueryExpressionNode GetNodeParser(Expression expression, IDbModelStrategy modelStrategy) { SqlDbQueryExpressionNode expressionNode = null; switch (expression.NodeType) { case ExpressionType.NotEqual: expressionNode = new SqlDbQueryNotEqualExpressionNode(); break; case ExpressionType.Not: expressionNode = new SqlDbQueryNotExpressionNode(); break; case ExpressionType.Equal: expressionNode = new SqlDbQueryEqualExpressionNode(); break; case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: expressionNode = new SqlDbQueryGreaterThanExpressionNode(); break; case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: expressionNode = new SqlDbQueryLessThanExpressionNode(); break; case ExpressionType.Add: case ExpressionType.AddChecked: expressionNode = new SqlDbQueryAddExpressionNode(); break; case ExpressionType.Subtract: case ExpressionType.SubtractChecked: expressionNode = new SqlDbQuerySubstractExpressionNode(); break; case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: expressionNode = new SqlDbQueryMultiplyExpressionNode(); break; case ExpressionType.Divide: expressionNode = new SqlDbQueryDivideExpressionNode(); break; case ExpressionType.MemberAccess: expressionNode = new SqlDbQueryMemberAccessExpressionNode(); break; case ExpressionType.AndAlso: expressionNode = new SqlDbQueryAndAlsoExpressionNode(); break; case ExpressionType.OrElse: expressionNode = new SqlDbQueryOrElseExpressionNode(); break; case ExpressionType.Constant: expressionNode = new SqlDbQueryConstantExpressionNode(); break; case ExpressionType.Call: expressionNode = new SqlDbQueryCallExpressionNode(); break; case ExpressionType.Parameter: expressionNode = new SqlDbQueryParameterExpressionNode(); break; case ExpressionType.Convert: expressionNode = new SqlDbQueryConvertExpressionNode(); break; default: throw new NotSupportedException("ERROR_GIVEN_QUERY_EXPRESSION_TYPE_NOT_SUPPORTED"); } expressionNode.ModelStrategy = modelStrategy; return(expressionNode); }
public override string Parse(IDictionary <string, object> parameterDictionary, Expression expressionNode) { if (expressionNode is MemberExpression) { var name = ((MemberExpression)expressionNode).Member.Name; if (ModelStrategy == null) { return(name); } var propQuery = ModelStrategy.PropertyStrategies.Where(c => c.GetPropertyInfo().Name == name).ToList(); return((propQuery.Any()) ? propQuery.First().GetParameterName() : name); } if (expressionNode is UnaryExpression) { var exp = (UnaryExpression)expressionNode; if (exp.Operand is MemberExpression) { var me = (MemberExpression)exp.Operand; if (me.Expression.NodeType == ExpressionType.Constant) { var constantExp = new SqlDbQueryConstantExpressionNode() { ModelStrategy = ModelStrategy }; var value = Expression.Lambda(exp).Compile().DynamicInvoke(); return(constantExp.Parse(parameterDictionary, Expression.Constant(value))); } var name = me.Member.Name; if (ModelStrategy == null) { return(name); } var propQuery = ModelStrategy.PropertyStrategies.Where(c => c.GetPropertyInfo().Name == name).ToList(); return(propQuery.Any() ? propQuery.First().GetParameterName() : name); } if (exp.Operand is BinaryExpression) { var binaryExp = (BinaryExpression)exp.Operand; var binaryExpStringBuilder = new StringBuilder(); // handle left expression. var leftExpNode = SqlDbQueryExpressionFactory.GetNodeParser(binaryExp.Left, ModelStrategy); var rightExpNode = SqlDbQueryExpressionFactory.GetNodeParser(binaryExp.Right, ModelStrategy); binaryExpStringBuilder.Append(leftExpNode.Parse(parameterDictionary, binaryExp.Left)); switch (binaryExp.NodeType) { case ExpressionType.Equal: binaryExpStringBuilder.Append(" = "); break; case ExpressionType.NotEqual: binaryExpStringBuilder.Append(" <> "); break; case ExpressionType.GreaterThan: binaryExpStringBuilder.Append(" > "); break; case ExpressionType.GreaterThanOrEqual: binaryExpStringBuilder.Append(" >= "); break; case ExpressionType.LessThan: binaryExpStringBuilder.Append(" < "); break; case ExpressionType.LessThanOrEqual: binaryExpStringBuilder.Append(" <= "); break; case ExpressionType.AndAlso: binaryExpStringBuilder.Append(" AND "); break; case ExpressionType.OrElse: binaryExpStringBuilder.Append(" OR "); break; default: throw new NotSupportedException("ERROR_NOT_SUPPORTED_CONDITION_EXPRESSION_TYPE"); } binaryExpStringBuilder.Append(rightExpNode.Parse(parameterDictionary, binaryExp.Right)); return(binaryExpStringBuilder.ToString()); } if (exp.Operand is MethodCallExpression) { var callExpressionNode = new SqlDbQueryCallExpressionNode() { ModelStrategy = ModelStrategy }; return(callExpressionNode.Parse(parameterDictionary, exp.Operand)); } SqlDbQueryExpressionNode node; if (exp.NodeType == ExpressionType.Constant) { node = new SqlDbQueryConstantExpressionNode() { ModelStrategy = ModelStrategy }; return(node.Parse(parameterDictionary, exp)); } if (exp.NodeType != ExpressionType.Convert) { throw new NotSupportedException("ERROR_NOT_SUPPORTED_UNARY_EXPRESSION_TYPE"); } node = new SqlDbQueryConstantExpressionNode() { ModelStrategy = ModelStrategy }; return(node.Parse(parameterDictionary, Expression.Constant(Expression.Lambda(exp).Compile().DynamicInvoke()))); } throw new NotSupportedException("ERROR_NOT_SUPPORTED_EXPRESSION_TYPE"); }
public override string Parse(IDictionary <string, object> parameterDictionary, Expression expressionNode) { var exp = expressionNode as MemberExpression; var expressionBuilder = new StringBuilder(); if (exp.Member.MemberType == MemberTypes.Property) { if (exp.Expression == null) { var callExpression = new SqlDbQueryCallExpressionNode() { ModelStrategy = ModelStrategy }; expressionBuilder.Append(callExpression.Parse(parameterDictionary, exp)); } else { var expParser = SqlDbQueryExpressionFactory.GetNodeParser(exp.Expression, ModelStrategy); bool handled = false; foreach (var functionNode in _supportedFunctionNodes) { if (functionNode.CheckForHandle(exp.Member.Name)) { ((SqlDbQueryExpressionNode)functionNode).ModelStrategy = ModelStrategy; expressionBuilder.Append(functionNode.Parse(parameterDictionary, exp.Expression)); handled = true; break; } } if (!handled) { // get alias type. Type t = exp.Expression.Type; // check this is field (must render as parameter, not field) // solution referenced from // http://stackoverflow.com/questions/6635678/how-to-recognize-a-lambda-memberexpression-of-type-field-reference bool isQueryParameterProperty = exp.Member is PropertyInfo && !(exp.Expression.NodeType == ExpressionType.Parameter); var propQuery = ModelStrategy.PropertyStrategies.Where(c => c.GetPropertyInfo().Name == exp.Member.Name); if (propQuery.Any()) { if (!isQueryParameterProperty) { //if (this._requireToRenderAlias) //{ // expressionBuilder.Append(this.ModelStrategy.GetTableAlias()); // expressionBuilder.Append("."); //} expressionBuilder.Append(propQuery.First().GetParameterName()); } else { MemberExpression memberExp = exp.Expression as MemberExpression; string pname = ParameterUtils.CreateNewParameter(ref parameterDictionary); object value = null; if ((memberExp == null && exp.Expression is ConstantExpression)) { value = ExtractValueFromConstantExpression( (exp.Expression as ConstantExpression), exp.Member.Name, exp.Member.Name); } else if (memberExp.Expression is ConstantExpression) { value = ExtractValueFromConstantExpression( (memberExp.Expression as ConstantExpression), memberExp.Member.Name, exp.Member.Name); } else { value = ExecuteLambdaExpression(exp); } if (value.GetType() == typeof(DateTime)) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = Convert.ToDateTime(value); } else if (value.GetType() == typeof(Guid)) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = new Guid(value.ToString()); } else if (exp.Type == typeof(byte[]) || exp.Type == typeof(byte)) { if (value != null) { byte[] byteArrayData = null; if (exp.Type == typeof(byte[])) { byteArrayData = (byte[])value; } else { byteArrayData = new byte[] { (byte)value } }; expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = byteArrayData; //expressionBuilder.Append("CONVERT(varbinary(max), "); //expressionBuilder.Append("0x" + byteArrayData.ToHexString(true)); //expressionBuilder.Append(")"); } } else if (value.GetType().IsValueType) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = value; } else { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = value.ToString(); } } } else { if (!isQueryParameterProperty) { //if (this._requireToRenderAlias) //{ // expressionBuilder.Append(this.ModelStrategy.GetTableAlias()); // expressionBuilder.Append("."); //} expressionBuilder.Append(exp.Member.Name); } else { MemberExpression memberExp = exp.Expression as MemberExpression; string pname = ParameterUtils.CreateNewParameter(ref parameterDictionary); object value = null; if (memberExp.Expression is ConstantExpression) { var constantExp = memberExp.Expression as ConstantExpression; value = ExtractValueFromConstantExpression( constantExp, memberExp.Member.Name, exp.Member.Name); } else { value = ExecuteLambdaExpression(exp); } if (value.GetType() == typeof(DateTime)) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = Convert.ToDateTime(value); } else if (value.GetType() == typeof(Guid)) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = new Guid(value.ToString()); } else if (exp.Type == typeof(byte[]) || exp.Type == typeof(byte)) { if (value != null) { byte[] byteArrayData = null; if (exp.Type == typeof(byte[])) { byteArrayData = (byte[])value; } else { byteArrayData = new byte[] { (byte)value } }; expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = byteArrayData; //expressionBuilder.Append("CONVERT(varbinary(max), "); //expressionBuilder.Append("0x" + byteArrayData.ToHexString(true)); //expressionBuilder.Append(")"); } } else if (exp.Type.IsArray) { object[] array = value as object[]; bool isFirst = true; expressionBuilder.Append("("); foreach (object arrayValue in array) { string arrayPName = ParameterUtils.CreateNewParameter(ref parameterDictionary); if (!isFirst) { expressionBuilder.Append(","); expressionBuilder.Append(string.Format("@{0}", arrayPName)); if (arrayValue is string) { parameterDictionary[arrayPName] = arrayValue.ToString(); } else { parameterDictionary[arrayPName] = arrayValue; } } else { expressionBuilder.Append(string.Format("@{0}", arrayPName)); if (arrayValue is string) { parameterDictionary[arrayPName] = arrayValue.ToString(); } else { parameterDictionary[arrayPName] = arrayValue; } isFirst = false; } } expressionBuilder.Append(")"); } else if (value.GetType().IsValueType) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = value; } else { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = value.ToString(); } } } } } } else if (exp.Member.MemberType == MemberTypes.Field) { object v = Expression.Lambda(exp).Compile().DynamicInvoke(); string pname = ParameterUtils.CreateNewParameter(ref parameterDictionary); if (exp.Type == typeof(string)) { if (v != null) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = v.ToString(); } else { parameterDictionary[pname] = DBNull.Value; } } else if (exp.Type == typeof(DateTime)) { if (v != null) { expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = Convert.ToDateTime(v); } } else if (exp.Type == typeof(byte[]) || exp.Type == typeof(byte)) { if (v != null) { byte[] byteArrayData = null; if (exp.Type == typeof(byte[])) { byteArrayData = (byte[])v; } else { byteArrayData = new byte[] { (byte)v } }; expressionBuilder.Append(string.Format("@{0}", pname)); parameterDictionary[pname] = Convert.ToDateTime(v); //expressionBuilder.Append("CONVERT(varbinary(max), "); //expressionBuilder.Append("0x" + byteArrayData.ToHexString(true)); //expressionBuilder.Append(")"); } } else if (exp.Type.IsArray) { object[] array = v as object[]; bool isFirst = true; expressionBuilder.Append("("); foreach (object arrayValue in array) { string arrayPName = ParameterUtils.CreateNewParameter(ref parameterDictionary); if (!isFirst) { expressionBuilder.Append(","); expressionBuilder.Append(string.Format("@{0}", arrayPName)); if (arrayValue is string) { parameterDictionary[arrayPName] = arrayValue.ToString(); } else { parameterDictionary[arrayPName] = arrayValue; } } else { expressionBuilder.Append(string.Format("@{0}", arrayPName)); if (arrayValue is string) { parameterDictionary[arrayPName] = arrayValue.ToString(); } else { parameterDictionary[arrayPName] = arrayValue; } isFirst = false; } } expressionBuilder.Append(")"); } else { expressionBuilder.Append(v.ToString()); } } else { var propQuery = ModelStrategy.PropertyStrategies.Where(c => c.GetPropertyInfo().Name == exp.Member.Name); if (propQuery.Any()) { //if (this._requireToRenderAlias) //{ // expressionBuilder.Append(this.ModelStrategy.GetTableAlias()); // expressionBuilder.Append("."); //} expressionBuilder.Append(propQuery.First().GetParameterName()); } else { //if (this._requireToRenderAlias) //{ // expressionBuilder.Append(this.ModelStrategy.GetTableAlias()); // expressionBuilder.Append("."); //} expressionBuilder.Append(exp.Member.Name); } } return(expressionBuilder.ToString()); }