internal SqlExpression TranslateEquals(SqlBinary expr) { var sqlExpression = expr.Left; var sqlExpression2 = expr.Right; if (sqlExpression2.NodeType == SqlNodeType.Element) { var sqlSubSelect = (SqlSubSelect)sqlExpression2; var sqlAlias = new SqlAlias(sqlSubSelect.Select); var sqlAliasRef = new SqlAliasRef(sqlAlias); var sqlSelect = new SqlSelect(sqlAliasRef, sqlAlias, expr.SourceExpression) { Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(sqlExpression), sqlAliasRef) }; return(sql.SubSelect(SqlNodeType.Exists, sqlSelect)); } if (sqlExpression.NodeType == SqlNodeType.Element) { var sqlSubSelect2 = (SqlSubSelect)sqlExpression; var sqlAlias2 = new SqlAlias(sqlSubSelect2.Select); var sqlAliasRef2 = new SqlAliasRef(sqlAlias2); var sqlSelect2 = new SqlSelect(sqlAliasRef2, sqlAlias2, expr.SourceExpression) { Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(sqlExpression2), sqlAliasRef2) }; return(sql.SubSelect(SqlNodeType.Exists, sqlSelect2)); } MetaType sourceMetaType = TypeSource.GetSourceMetaType(sqlExpression, services.Model); MetaType sourceMetaType2 = TypeSource.GetSourceMetaType(sqlExpression2, services.Model); if (sqlExpression.NodeType == SqlNodeType.TypeCase) { sqlExpression = BestIdentityNode((SqlTypeCase)sqlExpression); } if (sqlExpression2.NodeType == SqlNodeType.TypeCase) { sqlExpression2 = BestIdentityNode((SqlTypeCase)sqlExpression2); } if (sourceMetaType.IsEntity && sourceMetaType2.IsEntity && sourceMetaType.Table != sourceMetaType2.Table) { throw Error.CannotCompareItemsAssociatedWithDifferentTable(); } if (!sourceMetaType.IsEntity && !sourceMetaType2.IsEntity && (sqlExpression.NodeType != SqlNodeType.New || sqlExpression.SqlType.CanBeColumn) && (sqlExpression2.NodeType != SqlNodeType.New || sqlExpression2.SqlType.CanBeColumn)) { if (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) { return(TranslateEqualsOp(expr.NodeType, sql.DoNotVisitExpression(expr.Left), sql.DoNotVisitExpression(expr.Right), false)); } return(expr); } if (sourceMetaType != sourceMetaType2 && sourceMetaType.InheritanceRoot != sourceMetaType2.InheritanceRoot) { return(sql.Binary(SqlNodeType.EQ, sql.ValueFromObject(0, expr.SourceExpression), sql.ValueFromObject(1, expr.SourceExpression))); } var sqlLink = sqlExpression as SqlLink; var list = (sqlLink == null || !sqlLink.Member.IsAssociation || !sqlLink.Member.Association.IsForeignKey) ? GetIdentityExpressions(sourceMetaType, sql.DoNotVisitExpression(sqlExpression)) : sqlLink.KeyExpressions; var sqlLink2 = sqlExpression2 as SqlLink; var list2 = (sqlLink2 == null || !sqlLink2.Member.IsAssociation || !sqlLink2.Member.Association.IsForeignKey) ? GetIdentityExpressions(sourceMetaType2, sql.DoNotVisitExpression(sqlExpression2)) : sqlLink2.KeyExpressions; SqlExpression sqlExpression3 = null; var op = (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) ? SqlNodeType.EQ2V : SqlNodeType.EQ; var i = 0; for (var count = list.Count; i < count; i++) { var sqlExpression4 = TranslateEqualsOp(op, list[i], list2[i], !sourceMetaType.IsEntity); sqlExpression3 = ((sqlExpression3 != null) ? sql.Binary(SqlNodeType.And, sqlExpression3, sqlExpression4) : sqlExpression4); } if (expr.NodeType == SqlNodeType.NE || expr.NodeType == SqlNodeType.NE2V) { sqlExpression3 = sql.Unary(SqlNodeType.Not, sqlExpression3, sqlExpression3.SourceExpression); } return(sqlExpression3); }
internal SqlExpression TranslateEquals(SqlBinary expr) { System.Diagnostics.Debug.Assert( expr.NodeType == SqlNodeType.EQ || expr.NodeType == SqlNodeType.NE || expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V); SqlExpression eLeft = expr.Left; SqlExpression eRight = expr.Right; if (eRight.NodeType == SqlNodeType.Element) { SqlSubSelect sub = (SqlSubSelect)eRight; SqlAlias alias = new SqlAlias(sub.Select); SqlAliasRef aref = new SqlAliasRef(alias); SqlSelect select = new SqlSelect(aref, alias, expr.SourceExpression); select.Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(eLeft), aref); return(sql.SubSelect(SqlNodeType.Exists, select)); } else if (eLeft.NodeType == SqlNodeType.Element) { SqlSubSelect sub = (SqlSubSelect)eLeft; SqlAlias alias = new SqlAlias(sub.Select); SqlAliasRef aref = new SqlAliasRef(alias); SqlSelect select = new SqlSelect(aref, alias, expr.SourceExpression); select.Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(eRight), aref); return(sql.SubSelect(SqlNodeType.Exists, select)); } MetaType mtLeft = TypeSource.GetSourceMetaType(eLeft, this.services.Model); MetaType mtRight = TypeSource.GetSourceMetaType(eRight, this.services.Model); if (eLeft.NodeType == SqlNodeType.TypeCase) { eLeft = BestIdentityNode((SqlTypeCase)eLeft); } if (eRight.NodeType == SqlNodeType.TypeCase) { eRight = BestIdentityNode((SqlTypeCase)eRight); } if (mtLeft.IsEntity && mtRight.IsEntity && mtLeft.Table != mtRight.Table) { throw Error.CannotCompareItemsAssociatedWithDifferentTable(); } // do simple or no translation for non-structural types if (!mtLeft.IsEntity && !mtRight.IsEntity && (eLeft.NodeType != SqlNodeType.New || eLeft.SqlType.CanBeColumn) && (eRight.NodeType != SqlNodeType.New || eRight.SqlType.CanBeColumn)) { if (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) { return(this.TranslateEqualsOp(expr.NodeType, sql.DoNotVisitExpression(expr.Left), sql.DoNotVisitExpression(expr.Right), false)); } return(expr); } // If the two types are not comparable, we return the predicate "1=0". if ((mtLeft != mtRight) && (mtLeft.InheritanceRoot != mtRight.InheritanceRoot)) { return(sql.Binary(SqlNodeType.EQ, sql.ValueFromObject(0, expr.SourceExpression), sql.ValueFromObject(1, expr.SourceExpression))); } List <SqlExpression> exprs1; List <SqlExpression> exprs2; SqlLink link1 = eLeft as SqlLink; if (link1 != null && link1.Member.IsAssociation && link1.Member.Association.IsForeignKey) { exprs1 = link1.KeyExpressions; } else { exprs1 = this.GetIdentityExpressions(mtLeft, sql.DoNotVisitExpression(eLeft)); } SqlLink link2 = eRight as SqlLink; if (link2 != null && link2.Member.IsAssociation && link2.Member.Association.IsForeignKey) { exprs2 = link2.KeyExpressions; } else { exprs2 = this.GetIdentityExpressions(mtRight, sql.DoNotVisitExpression(eRight)); } System.Diagnostics.Debug.Assert(exprs1.Count > 0); System.Diagnostics.Debug.Assert(exprs2.Count > 0); System.Diagnostics.Debug.Assert(exprs1.Count == exprs2.Count); SqlExpression exp = null; SqlNodeType eqKind = (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) ? SqlNodeType.EQ2V : SqlNodeType.EQ; for (int i = 0, n = exprs1.Count; i < n; i++) { SqlExpression eq = this.TranslateEqualsOp(eqKind, exprs1[i], exprs2[i], !mtLeft.IsEntity); if (exp == null) { exp = eq; } else { exp = sql.Binary(SqlNodeType.And, exp, eq); } } if (expr.NodeType == SqlNodeType.NE || expr.NodeType == SqlNodeType.NE2V) { exp = sql.Unary(SqlNodeType.Not, exp, exp.SourceExpression); } return(exp); }
internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { mc.Object = this.VisitExpression(mc.Object); for (int i = 0, n = mc.Arguments.Count; i < n; i++) { mc.Arguments[i] = this.VisitExpression(mc.Arguments[i]); } if (mc.Method.IsStatic) { if (mc.Method.Name == "Equals" && mc.Arguments.Count == 2) { return(sql.Binary(SqlNodeType.EQ2V, mc.Arguments[0], mc.Arguments[1], mc.Method)); } else if (mc.Method.DeclaringType == typeof(string) && mc.Method.Name == "Concat") { SqlClientArray arr = mc.Arguments[0] as SqlClientArray; List <SqlExpression> exprs = null; if (arr != null) { exprs = arr.Expressions; } else { exprs = mc.Arguments; } if (exprs.Count == 0) { return(sql.ValueFromObject("", false, mc.SourceExpression)); } else { SqlExpression sum; if (exprs[0].SqlType.IsString || exprs[0].SqlType.IsChar) { sum = exprs[0]; } else { sum = sql.ConvertTo(typeof(string), exprs[0]); } for (int i = 1; i < exprs.Count; i++) { if (exprs[i].SqlType.IsString || exprs[i].SqlType.IsChar) { sum = sql.Concat(sum, exprs[i]); } else { sum = sql.Concat(sum, sql.ConvertTo(typeof(string), exprs[i])); } } return(sum); } } else if (IsVbIIF(mc)) { return(TranslateVbIIF(mc)); } else { switch (mc.Method.Name) { case "op_Equality": return(sql.Binary(SqlNodeType.EQ, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_Inequality": return(sql.Binary(SqlNodeType.NE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_LessThan": return(sql.Binary(SqlNodeType.LT, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_LessThanOrEqual": return(sql.Binary(SqlNodeType.LE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_GreaterThan": return(sql.Binary(SqlNodeType.GT, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_GreaterThanOrEqual": return(sql.Binary(SqlNodeType.GE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_Multiply": return(sql.Binary(SqlNodeType.Mul, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_Division": return(sql.Binary(SqlNodeType.Div, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_Subtraction": return(sql.Binary(SqlNodeType.Sub, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_Addition": return(sql.Binary(SqlNodeType.Add, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_Modulus": return(sql.Binary(SqlNodeType.Mod, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_BitwiseAnd": return(sql.Binary(SqlNodeType.BitAnd, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_BitwiseOr": return(sql.Binary(SqlNodeType.BitOr, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_ExclusiveOr": return(sql.Binary(SqlNodeType.BitXor, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType)); case "op_UnaryNegation": return(sql.Unary(SqlNodeType.Negate, mc.Arguments[0], mc.Method, mc.SourceExpression)); case "op_OnesComplement": return(sql.Unary(SqlNodeType.BitNot, mc.Arguments[0], mc.Method, mc.SourceExpression)); case "op_False": return(sql.Unary(SqlNodeType.Not, mc.Arguments[0], mc.Method, mc.SourceExpression)); } } } else { if (mc.Method.Name == "Equals" && mc.Arguments.Count == 1) { return(sql.Binary(SqlNodeType.EQ, mc.Object, mc.Arguments[0])); } else if (mc.Method.Name == "GetType" && mc.Arguments.Count == 0) { MetaType mt = TypeSource.GetSourceMetaType(mc.Object, this.model); if (mt.HasInheritance) { Type discriminatorType = mt.Discriminator.Type; SqlDiscriminatorOf discriminatorOf = new SqlDiscriminatorOf(mc.Object, discriminatorType, this.sql.TypeProvider.From(discriminatorType), mc.SourceExpression); return(this.VisitExpression(sql.DiscriminatedType(discriminatorOf, mt))); } return(this.VisitExpression(sql.StaticType(mt, mc.SourceExpression))); } } return(mc); }