static void EnsureTrimCharArgumentIsSpaces(DbExpression exp) { var m = exp as DbMemberExpression; if (m == null) { throw new NotSupportedException(); } DbParameterExpression p; if (!DbExpressionExtension.TryConvertToParameterExpression(m, out p)) { throw new NotSupportedException(); } var arg = p.Value; if (arg == null) { throw new NotSupportedException(); } var chars = arg as char[]; if (chars.Length != 1 || chars[0] != ' ') { throw new NotSupportedException(); } }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { DbExpression left = exp.Arguments[0]; DbExpression right = exp.Arguments[1]; left = DbExpressionExtension.StripInvalidConvert(left); right = DbExpressionExtension.StripInvalidConvert(right); //明确 left right 其中一边一定为 null if (DbExpressionExtension.AffirmExpressionRetValueIsNull(right)) { left.Accept(generator); generator.SqlBuilder.Append(" IS NOT NULL"); return; } if (DbExpressionExtension.AffirmExpressionRetValueIsNull(left)) { right.Accept(generator); generator.SqlBuilder.Append(" IS NOT NULL"); return; } SqlGenerator.AmendDbInfo(left, right); left.Accept(generator); generator.SqlBuilder.Append(" <> "); right.Accept(generator); }
public override DbExpression Visit(DbEqualExpression exp) { DbExpression left = exp.Left; DbExpression right = exp.Right; left = DbExpressionHelper.OptimizeDbExpression(left); right = DbExpressionHelper.OptimizeDbExpression(right); //明确 left right 其中一边一定为 null if (DbExpressionExtension.AffirmExpressionRetValueIsNull(right)) { left.Accept(this); this._sqlBuilder.Append(" IS NULL"); return(exp); } if (DbExpressionExtension.AffirmExpressionRetValueIsNull(left)) { right.Accept(this); this._sqlBuilder.Append(" IS NULL"); return(exp); } AmendDbInfo(left, right); left.Accept(this); this._sqlBuilder.Append(" = "); right.Accept(this); return(exp); }
static void Method_Sql_Equals(DbMethodCallExpression exp, SqlGenerator generator) { DbExpression left = exp.Arguments[0]; DbExpression right = exp.Arguments[1]; left = DbExpressionExtension.StripInvalidConvert(left); right = DbExpressionExtension.StripInvalidConvert(right); //明确 left right 其中一边一定为 null if (DbExpressionHelper.AffirmExpressionRetValueIsNullOrEmpty(right)) { left.Accept(generator); generator.SqlBuilder.Append(" IS NULL"); return; } if (DbExpressionHelper.AffirmExpressionRetValueIsNullOrEmpty(left)) { right.Accept(generator); generator.SqlBuilder.Append(" IS NULL"); return; } SqlGenerator.AmendDbInfo(left, right); left.Accept(generator); generator.SqlBuilder.Append(" = "); right.Accept(generator); }
static void Method_Sql_Equals(DbMethodCallExpression exp, SqlGenerator generator) { DbExpression left = exp.Arguments[0]; DbExpression right = exp.Arguments[1]; left = DbExpressionHelper.OptimizeDbExpression(left); right = DbExpressionHelper.OptimizeDbExpression(right); //明确 left right 其中一边一定为 null if (DbExpressionExtension.AffirmExpressionRetValueIsNull(right)) { left.Accept(generator); generator._sqlBuilder.Append(" IS NULL"); return; } if (DbExpressionExtension.AffirmExpressionRetValueIsNull(left)) { right.Accept(generator); generator._sqlBuilder.Append(" IS NULL"); return; } AmendDbInfo(left, right); left.Accept(generator); generator._sqlBuilder.Append(" = "); right.Accept(generator); return; }
/// <summary> /// 尝试将 exp 转换成 DbParameterExpression。 /// </summary> /// <param name="exp"></param> /// <returns></returns> public static DbExpression OptimizeDbExpression(this DbExpression exp) { DbExpression stripedExp = DbExpressionExtension.StripInvalidConvert(exp); DbExpression tempExp = stripedExp; List <DbConvertExpression> cList = null; while (tempExp.NodeType == DbExpressionType.Convert) { if (cList == null) { cList = new List <DbConvertExpression>(); } DbConvertExpression c = (DbConvertExpression)tempExp; cList.Add(c); tempExp = c.Operand; } if (tempExp.NodeType == DbExpressionType.Constant || tempExp.NodeType == DbExpressionType.Parameter) { return(stripedExp); } if (tempExp.NodeType == DbExpressionType.MemberAccess) { DbMemberExpression dbMemberExp = (DbMemberExpression)tempExp; if (ExistDateTime_NowOrDateTime_UtcNow(dbMemberExp)) { return(stripedExp); } DbParameterExpression val; if (DbExpressionExtension.TryConvertToParameterExpression(dbMemberExp, out val)) { if (cList != null) { if (val.Value == DBNull.Value)//如果是 null,则不需要 Convert 了,在数据库里没意义 { return(val); } DbConvertExpression c = null; for (int i = cList.Count - 1; i > -1; i--) { DbConvertExpression item = cList[i]; c = new DbConvertExpression(item.Type, val); } return(c); } return(val); } } return(stripedExp); }
public override DbExpression Visit(DbMemberExpression exp) { MemberInfo member = exp.Member; if (member.DeclaringType == UtilConstants.TypeOfDateTime) { if (member == UtilConstants.PropertyInfo_DateTime_Now) { this._sqlBuilder.Append("GETDATE()"); return(exp); } if (member == UtilConstants.PropertyInfo_DateTime_UtcNow) { this._sqlBuilder.Append("GETUTCDATE()"); return(exp); } if (member == UtilConstants.PropertyInfo_DateTime_Today) { this.BuildCastState("GETDATE()", "DATE"); return(exp); } if (member == UtilConstants.PropertyInfo_DateTime_Date) { this.BuildCastState(exp.Expression, "DATE"); return(exp); } if (this.IsDatePart(exp)) { return(exp); } } DbParameterExpression newExp; if (DbExpressionExtension.TryConvertToParameterExpression(exp, out newExp)) { return(newExp.Accept(this)); } if (member.Name == "Length" && member.DeclaringType == UtilConstants.TypeOfString) { this._sqlBuilder.Append("LEN("); exp.Expression.Accept(this); this._sqlBuilder.Append(")"); return(exp); } else if (member.Name == "Value" && ReflectionExtension.IsNullable(exp.Expression.Type)) { exp.Expression.Accept(this); return(exp); } throw new NotSupportedException(string.Format("'{0}.{1}' is not supported.", member.DeclaringType.FullName, member.Name)); }
public override DbExpression Visit(DbUpdateExpression exp) { this._sqlBuilder.Append("UPDATE "); this.AppendTable(exp.Table); this._sqlBuilder.Append(" SET "); bool first = true; foreach (var item in exp.UpdateColumns) { if (first) { first = false; } else { this._sqlBuilder.Append(","); } this.QuoteName(item.Key.Name); this._sqlBuilder.Append("="); DbExpression valExp = DbExpressionExtension.StripInvalidConvert(item.Value); AmendDbInfo(item.Key, valExp); valExp.Accept(this.ValueExpressionVisitor); } this.BuildWhereState(exp.Condition); return(exp); }
public override DbExpression Visit(DbConvertExpression exp) { DbExpression stripedExp = DbExpressionExtension.StripInvalidConvert(exp); if (stripedExp.NodeType != DbExpressionType.Convert) { stripedExp.Accept(this); return(exp); } exp = (DbConvertExpression)stripedExp; string dbTypeString; if (TryGetCastTargetDbTypeString(exp.Operand.Type, exp.Type, out dbTypeString, false)) { this.BuildCastState(exp.Operand, dbTypeString); } else { exp.Operand.Accept(this); } return(exp); }
static void Method_Contains(DbMethodCallExpression exp, SqlGenerator generator) { MethodInfo method = exp.Method; if (method.DeclaringType == UtilConstants.TypeOfString) { 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))) { DbMemberExpression memberExp = exp.Object as DbMemberExpression; if (memberExp == null || !memberExp.IsEvaluable()) { throw new NotSupportedException(exp.ToString()); } values = DbExpressionExtension.Evaluate(memberExp) as IEnumerable; //Enumerable operand = exp.Arguments[0]; goto constructInState; } if (method.IsStatic && declaringType == typeof(Enumerable) && exp.Arguments.Count == 2) { DbMemberExpression memberExp = exp.Arguments[0] as DbMemberExpression; if (memberExp == null || !memberExp.IsEvaluable()) { throw new NotSupportedException(exp.ToString()); } values = DbExpressionExtension.Evaluate(memberExp) 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 { exps.Add(DbExpression.Parameter(value)); } } In(generator, exps, operand); }
public override DbExpression Visit(DbEqualExpression exp) { DbExpression left = exp.Left; DbExpression right = exp.Right; left = DbExpressionExtension.StripInvalidConvert(left); right = DbExpressionExtension.StripInvalidConvert(right); MethodInfo method_Sql_Equals = PublicConstants.MethodInfo_Sql_Equals.MakeGenericMethod(left.Type); /* Sql.Equals(left, right) */ DbMethodCallExpression left_equals_right = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { left, right }); if (right.NodeType == DbExpressionType.Parameter || right.NodeType == DbExpressionType.Constant || left.NodeType == DbExpressionType.Parameter || left.NodeType == DbExpressionType.Constant || right.NodeType == DbExpressionType.SubQuery || left.NodeType == DbExpressionType.SubQuery || !left.Type.CanNull() || !right.Type.CanNull()) { /* * a.Name == name --> a.Name == name * a.Id == (select top 1 T.Id from T) --> a.Id == (select top 1 T.Id from T) * 对于上述查询,我们不考虑 null */ left_equals_right.Accept(this); return(exp); } /* * a.Name == a.XName --> a.Name == a.XName or (a.Name is null and a.XName is null) */ /* Sql.Equals(left, null) */ var left_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { left, DbExpression.Constant(null, left.Type) }); /* Sql.Equals(right, null) */ var right_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { right, DbExpression.Constant(null, right.Type) }); /* Sql.Equals(left, null) && Sql.Equals(right, null) */ var left_is_null_and_right_is_null = DbExpression.And(left_is_null, right_is_null); /* Sql.Equals(left, right) || (Sql.Equals(left, null) && Sql.Equals(right, null)) */ var left_equals_right_or_left_is_null_and_right_is_null = DbExpression.Or(left_equals_right, left_is_null_and_right_is_null); left_equals_right_or_left_is_null_and_right_is_null.Accept(this); return(exp); }
public override DbExpression Visit(DbInsertExpression exp) { string separator = ""; this._sqlBuilder.Append("INSERT INTO "); this.AppendTable(exp.Table); this._sqlBuilder.Append("("); separator = ""; foreach (var item in exp.InsertColumns) { this._sqlBuilder.Append(separator); this.QuoteName(item.Key.Name); separator = ","; } this._sqlBuilder.Append(")"); if (exp.Returns.Count > 0) { this._sqlBuilder.Append(" output "); separator = ""; foreach (DbColumn returnColumn in exp.Returns) { this._sqlBuilder.Append(separator); this._sqlBuilder.Append("inserted."); this.QuoteName(returnColumn.Name); separator = ","; } } this._sqlBuilder.Append(" VALUES("); separator = ""; foreach (var item in exp.InsertColumns) { this._sqlBuilder.Append(separator); DbExpression valExp = DbExpressionExtension.StripInvalidConvert(item.Value); AmendDbInfo(item.Key, valExp); valExp.Accept(this.ValueExpressionVisitor); separator = ","; } this._sqlBuilder.Append(")"); return(exp); }
/// <summary> /// 判定 exp 返回值肯定是 null 或 '' /// </summary> /// <param name="exp"></param> /// <returns></returns> public static bool AffirmExpressionRetValueIsNullOrEmpty(this DbExpression exp) { exp = DbExpressionExtension.StripConvert(exp); if (exp.NodeType == DbExpressionType.Constant) { var c = (DbConstantExpression)exp; return(IsNullOrEmpty(c.Value)); } if (exp.NodeType == DbExpressionType.Parameter) { var p = (DbParameterExpression)exp; return(IsNullOrEmpty(p.Value)); } return(false); }
public override DbExpression Visit(DbConvertExpression exp) { DbExpression stripedExp = DbExpressionExtension.StripInvalidConvert(exp); if (stripedExp.NodeType != DbExpressionType.Convert) { EnsureDbExpressionReturnCSharpBoolean(stripedExp).Accept(this); return(exp); } exp = (DbConvertExpression)stripedExp; if (exp.Type == PublicConstants.TypeOfString) { this.SqlBuilder.Append("TO_CHAR("); exp.Operand.Accept(this); this.SqlBuilder.Append(")"); return(exp); } if (exp.Type == PublicConstants.TypeOfDateTime) { this.SqlBuilder.Append("TO_TIMESTAMP("); exp.Operand.Accept(this); this.SqlBuilder.Append(",'yyyy-mm-dd hh24:mi:ssxff')"); return(exp); } string dbTypeString; if (TryGetCastTargetDbTypeString(exp.Operand.Type, exp.Type, out dbTypeString, false)) { this.BuildCastState(EnsureDbExpressionReturnCSharpBoolean(exp.Operand), dbTypeString); } else { EnsureDbExpressionReturnCSharpBoolean(exp.Operand).Accept(this); } return(exp); }
static void Method_NotEquals(DbMethodCallExpression exp, SqlGenerator generator) { MethodInfo method = exp.Method; if (method.DeclaringType != UtilConstants.TypeOfSql) { throw UtilExceptions.NotSupportedMethod(method); } DbExpression left = exp.Arguments[0]; DbExpression right = exp.Arguments[1]; left = DbExpressionHelper.OptimizeDbExpression(left); right = DbExpressionHelper.OptimizeDbExpression(right); //明确 left right 其中一边一定为 null if (DbExpressionExtension.AffirmExpressionRetValueIsNull(right)) { left.Accept(generator); generator._sqlBuilder.Append(" IS NOT NULL"); return; } if (DbExpressionExtension.AffirmExpressionRetValueIsNull(left)) { right.Accept(generator); generator._sqlBuilder.Append(" IS NOT NULL"); return; } AmendDbInfo(left, right); left.Accept(generator); generator._sqlBuilder.Append(" <> "); right.Accept(generator); return; }
public override DbExpression Visit(DbInsertExpression exp) { string separator = ""; this._sqlBuilder.Append("INSERT INTO "); this.AppendTable(exp.Table); this._sqlBuilder.Append("("); separator = ""; foreach (var item in exp.InsertColumns) { this._sqlBuilder.Append(separator); this.QuoteName(item.Key.Name); separator = ","; } this._sqlBuilder.Append(")"); this.AppendOutputClause(exp.Returns); this._sqlBuilder.Append(" VALUES("); separator = ""; foreach (var item in exp.InsertColumns) { this._sqlBuilder.Append(separator); DbExpression valExp = DbExpressionExtension.StripInvalidConvert(item.Value); AmendDbInfo(item.Key, valExp); DbValueExpressionTransformer.Transform(valExp).Accept(this); separator = ","; } this._sqlBuilder.Append(")"); return(exp); }
public override DbExpression Visit(DbConvertExpression exp) { DbExpression stripedExp = DbExpressionExtension.StripInvalidConvert(exp); if (stripedExp.NodeType != DbExpressionType.Convert) { stripedExp.Accept(this); return(exp); } exp = (DbConvertExpression)stripedExp; string dbTypeString; if (TryGetCastTargetDbTypeString(exp.Operand.Type, exp.Type, out dbTypeString, false)) { this.BuildCastState(exp.Operand, dbTypeString); } else { Type targetType = ReflectionExtension.GetUnderlyingType(exp.Type); if (targetType == PublicConstants.TypeOfDateTime) { /* DATETIME('2016-08-06 09:01:24') */ this.SqlBuilder.Append("DATETIME("); exp.Operand.Accept(this); this.SqlBuilder.Append(")"); } else { exp.Operand.Accept(this); } } return(exp); }
public override DbExpression Visit(DbMemberExpression exp) { MemberInfo member = exp.Member; if (member == OracleSemantics.PropertyInfo_ROWNUM) { this.SqlBuilder.Append("ROWNUM"); return(exp); } if (member.DeclaringType == PublicConstants.TypeOfDateTime) { if (member == PublicConstants.PropertyInfo_DateTime_Now) { this.SqlBuilder.Append("SYSTIMESTAMP"); return(exp); } if (member == PublicConstants.PropertyInfo_DateTime_UtcNow) { this.SqlBuilder.Append("SYS_EXTRACT_UTC(SYSTIMESTAMP)"); return(exp); } if (member == PublicConstants.PropertyInfo_DateTime_Today) { //other way: this.SqlBuilder.Append("TO_DATE(TO_CHAR(SYSDATE,'yyyy-mm-dd'),'yyyy-mm-dd')"); this.SqlBuilder.Append("TRUNC(SYSDATE,'DD')"); return(exp); } if (member == PublicConstants.PropertyInfo_DateTime_Date) { this.SqlBuilder.Append("TRUNC("); exp.Expression.Accept(this); this.SqlBuilder.Append(",'DD')"); return(exp); } if (this.IsDatePart(exp)) { return(exp); } } if (this.IsDateSubtract(exp)) { return(exp); } if (member.Name == "Length" && member.DeclaringType == PublicConstants.TypeOfString) { this.SqlBuilder.Append("LENGTH("); exp.Expression.Accept(this); this.SqlBuilder.Append(")"); return(exp); } if (member.Name == "Value" && ReflectionExtension.IsNullable(exp.Expression.Type)) { exp.Expression.Accept(this); return(exp); } DbParameterExpression newExp; if (DbExpressionExtension.TryConvertToParameterExpression(exp, out newExp)) { return(newExp.Accept(this)); } throw new NotSupportedException(string.Format("'{0}.{1}' is not supported.", member.DeclaringType.FullName, member.Name)); }
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 = UtilConstants.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 = UtilConstants.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); }
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); }