public void Process(DbMethodCallExpression exp, SqlGenerator generator) { DbExpression e = exp.Arguments.First(); DbEqualExpression equalNullExpression = DbExpression.Equal(e, DbExpression.Constant(null, PublicConstants.TypeOfString)); DbEqualExpression equalEmptyExpression = DbExpression.Equal(e, DbExpression.Constant(string.Empty)); DbOrExpression orExpression = DbExpression.Or(equalNullExpression, equalEmptyExpression); DbCaseWhenExpression.WhenThenExpressionPair whenThenPair = new DbCaseWhenExpression.WhenThenExpressionPair(orExpression, DbConstantExpression.One); List <DbCaseWhenExpression.WhenThenExpressionPair> whenThenExps = new List <DbCaseWhenExpression.WhenThenExpressionPair>(1); whenThenExps.Add(whenThenPair); DbCaseWhenExpression caseWhenExpression = DbExpression.CaseWhen(whenThenExps, DbConstantExpression.Zero, PublicConstants.TypeOfBoolean); var eqExp = DbExpression.Equal(caseWhenExpression, DbConstantExpression.One); eqExp.Accept(generator); }
public override DbExpression Visit(DbExistsExpression exp) { this.SqlBuilder.Append("Exists "); DbSqlQueryExpression rawSqlQuery = exp.SqlQuery; DbSqlQueryExpression sqlQuery = new DbSqlQueryExpression() { TakeCount = rawSqlQuery.TakeCount, SkipCount = rawSqlQuery.SkipCount, Table = rawSqlQuery.Table, Condition = rawSqlQuery.Condition, HavingCondition = rawSqlQuery.HavingCondition, }; sqlQuery.GroupSegments.AddRange(rawSqlQuery.GroupSegments); DbColumnSegment columnSegment = new DbColumnSegment(DbExpression.Constant("1"), "C"); sqlQuery.ColumnSegments.Add(columnSegment); DbSubQueryExpression subQuery = new DbSubQueryExpression(sqlQuery); return(subQuery.Accept(this)); }
public override object Visit(DbConvertExpression exp) { object operandValue = exp.Operand.Accept(this); //(int)null if (operandValue == null) { //(int)null if (exp.Type.IsValueType && !exp.Type.IsNullable()) { throw new NullReferenceException(); } return(null); } Type operandValueType = operandValue.GetType(); if (exp.Type == operandValueType || exp.Type.IsAssignableFrom(operandValueType)) { return(operandValue); } Type underlyingType; if (exp.Type.IsNullable(out underlyingType)) { //(int?)int if (underlyingType == operandValueType) { var constructor = exp.Type.GetConstructor(new Type[] { operandValueType }); var val = constructor.Invoke(new object[] { operandValue }); return(val); } else { //如果不等,则诸如:(long?)int / (long?)int? --> (long?)((long)int) / (long?)((long)int?) var c = DbExpression.Convert(DbExpression.Constant(operandValue), underlyingType); var cc = DbExpression.Convert(c, exp.Type); return(this.Visit(cc)); } } //(int)int? if (operandValueType.IsNullable(out underlyingType)) { if (underlyingType == exp.Type) { var pro = operandValueType.GetProperty("Value"); var val = pro.GetValue(operandValue, null); return(val); } else { //如果不等,则诸如:(long)int? --> (long)((long)int) var c = DbExpression.Convert(DbExpression.Constant(operandValue), underlyingType); var cc = DbExpression.Convert(c, exp.Type); return(this.Visit(cc)); } } if (exp.Type.IsEnum) { return(Enum.ToObject(exp.Type, operandValue)); } //(long)int if (operandValue is IConvertible) { return(Convert.ChangeType(operandValue, exp.Type)); } throw new NotSupportedException(string.Format("Does not support the type '{0}' converted to type '{1}'.", operandValueType.FullName, exp.Type.FullName)); }
public void Process(DbMethodCallExpression exp, SqlGeneratorBase generator) { MethodInfo method = exp.Method; if (exp.Method == PublicConstants.MethodInfo_String_Contains) { Method_String_Contains(exp, generator); return; } List <DbExpression> exps = new List <DbExpression>(); IEnumerable values = null; DbExpression operand = null; Type declaringType = method.DeclaringType; if (typeof(IList).IsAssignableFrom(declaringType) || (declaringType.IsGenericType && typeof(ICollection <>).MakeGenericType(declaringType.GetGenericArguments()).IsAssignableFrom(declaringType))) { if (exp.Object.NodeType == DbExpressionType.SqlQuery) { /* where Id in(select id from T) */ operand = exp.Arguments[0]; In(generator, (DbSqlQueryExpression)exp.Object, operand); return; } if (!exp.Object.IsEvaluable()) { throw new NotSupportedException(exp.ToString()); } values = DbExpressionExtension.Evaluate(exp.Object) as IEnumerable; //Enumerable operand = exp.Arguments[0]; goto constructInState; } if (method.IsStatic && declaringType == typeof(Enumerable) && exp.Arguments.Count == 2) { DbExpression arg0 = exp.Arguments[0]; if (arg0.NodeType == DbExpressionType.SqlQuery) { /* where Id in(select id from T) */ operand = exp.Arguments[1]; In(generator, (DbSqlQueryExpression)arg0, operand); return; } if (!arg0.IsEvaluable()) { throw UtilExceptions.NotSupportedMethod(exp.Method); } values = DbExpressionExtension.Evaluate(arg0) as IEnumerable; operand = exp.Arguments[1]; goto constructInState; } throw UtilExceptions.NotSupportedMethod(exp.Method); constructInState: foreach (object value in values) { if (value == null) { exps.Add(DbExpression.Constant(null, operand.Type)); } else { Type valueType = value.GetType(); if (valueType.IsEnum) { valueType = Enum.GetUnderlyingType(valueType); } if (Utils.IsToStringableNumericType(valueType)) { exps.Add(DbExpression.Constant(value)); } else { exps.Add(DbExpression.Parameter(value)); } } } In(generator, exps, operand); }
public override DbExpression Visit(DbNotEqualExpression exp) { DbExpression left = exp.Left; DbExpression right = exp.Right; left = DbExpressionExtension.StripInvalidConvert(left); right = DbExpressionExtension.StripInvalidConvert(right); MethodInfo method_Sql_NotEquals = PublicConstants.MethodInfo_Sql_NotEquals.MakeGenericMethod(left.Type); /* Sql.NotEquals(left, right) */ DbMethodCallExpression left_not_equals_right = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2) { left, right }); //明确 left right 其中一边一定为 null if (DbExpressionExtension.AffirmExpressionRetValueIsNull(right) || DbExpressionExtension.AffirmExpressionRetValueIsNull(left)) { /* * a.Name != null --> a.Name != null */ left_not_equals_right.Accept(this); return(exp); } if (right.NodeType == DbExpressionType.SubQuery || left.NodeType == DbExpressionType.SubQuery) { /* * a.Id != (select top 1 T.Id from T) --> a.Id <> (select top 1 T.Id from T),对于这种查询,我们不考虑 null */ left_not_equals_right.Accept(this); return(exp); } MethodInfo method_Sql_Equals = PublicConstants.MethodInfo_Sql_Equals.MakeGenericMethod(left.Type); if (left.NodeType == DbExpressionType.Parameter || left.NodeType == DbExpressionType.Constant) { var t = right; right = left; left = t; } if (right.NodeType == DbExpressionType.Parameter || right.NodeType == DbExpressionType.Constant) { /* * 走到这说明 name 不可能为 null * a.Name != name --> a.Name <> name or a.Name is null */ if (left.NodeType != DbExpressionType.Parameter && left.NodeType != DbExpressionType.Constant) { /* * a.Name != name --> a.Name <> name or a.Name is null */ /* Sql.Equals(left, null) */ var left_is_null1 = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { left, DbExpression.Constant(null, left.Type) }); /* Sql.NotEquals(left, right) || Sql.Equals(left, null) */ var left_not_equals_right_or_left_is_null = DbExpression.Or(left_not_equals_right, left_is_null1); left_not_equals_right_or_left_is_null.Accept(this); } else { /* * name != name1 --> name <> name,其中 name 和 name1 都为变量且都不可能为 null */ left_not_equals_right.Accept(this); } return(exp); } /* * a.Name != a.XName --> a.Name <> a.XName or (a.Name is null and a.XName is not null) or (a.Name is not null and a.XName is null) * ## a.Name != a.XName 不能翻译成:not (a.Name == a.XName or (a.Name is null and a.XName is null)),因为数据库里的 not 有时候并非真正意义上的“取反”! * 当 a.Name 或者 a.XName 其中一个字段有为 NULL,另一个字段有值时,会查不出此条数据 ## */ DbConstantExpression null_Constant = DbExpression.Constant(null, left.Type); /* Sql.Equals(left, null) */ var left_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { left, null_Constant }); /* Sql.NotEquals(left, null) */ var left_is_not_null = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2) { left, null_Constant }); /* Sql.Equals(right, null) */ var right_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { right, null_Constant }); /* Sql.NotEquals(right, null) */ var right_is_not_null = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2) { right, null_Constant }); /* Sql.Equals(left, null) && Sql.NotEquals(right, null) */ var left_is_null_and_right_is_not_null = DbExpression.And(left_is_null, right_is_not_null); /* Sql.NotEquals(left, null) && Sql.Equals(right, null) */ var left_is_not_null_and_right_is_null = DbExpression.And(left_is_not_null, right_is_null); /* (Sql.Equals(left, null) && Sql.NotEquals(right, null)) || (Sql.NotEquals(left, null) && Sql.Equals(right, null)) */ var left_is_null_and_right_is_not_null_or_left_is_not_null_and_right_is_null = DbExpression.Or(left_is_null_and_right_is_not_null, left_is_not_null_and_right_is_null); /* Sql.NotEquals(left, right) || (Sql.Equals(left, null) && Sql.NotEquals(right, null)) || (Sql.NotEquals(left, null) && Sql.Equals(right, null)) */ var e = DbExpression.Or(left_not_equals_right, left_is_null_and_right_is_not_null_or_left_is_not_null_and_right_is_null); e.Accept(this); return(exp); }
static void AppendLimitCondition(DbSqlQueryExpression sqlQuery, int limitCount) { DbLessThanExpression lessThanExp = DbExpression.LessThan(OracleSemantics.DbMemberExpression_ROWNUM, DbExpression.Constant(limitCount + 1)); DbExpression condition = lessThanExp; if (sqlQuery.Condition != null) { condition = DbExpression.And(sqlQuery.Condition, condition); } sqlQuery.Condition = condition; }