internal virtual SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) { dof.Object = this.VisitExpression(dof.Object); return dof; }
internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) { if(_isDebugMode) { _commandStringBuilder.Append("DISCO("); } base.VisitDiscriminatorOf(dof); if(_isDebugMode) { _commandStringBuilder.Append(")"); } return dof; }
/// <summary> /// Evaluate the object and extract its discriminator. /// </summary> internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) { SqlExpression obj = this.FetchExpression(dof.Object); // FetchExpression removes Link. // It's valid to unwrap optional and outer-join values here because type case already handles // NULL values correctly. while (obj.NodeType == SqlNodeType.OptionalValue || obj.NodeType == SqlNodeType.OuterJoinedValue) { if (obj.NodeType == SqlNodeType.OptionalValue) { obj = ((SqlOptionalValue)obj).Value; } else { obj = ((SqlUnary)obj).Operand; } } if (obj.NodeType == SqlNodeType.TypeCase) { SqlTypeCase tc = (SqlTypeCase)obj; // Rewrite a case of discriminators. We can't just reduce to // discriminator (yet) because the ELSE clause needs to be considered. // Later in the conversion there is an optimization that will turn the CASE // into a simple combination of ANDs and ORs. // Also, cannot reduce to IsNull(Discriminator,DefaultDiscriminator) because // other unexpected values besides NULL need to be handled. List<SqlExpression> matches = new List<SqlExpression>(); List<SqlExpression> values = new List<SqlExpression>(); MetaType defaultType = tc.RowType.InheritanceDefault; object discriminator = defaultType.InheritanceCode; foreach (SqlTypeCaseWhen when in tc.Whens) { matches.Add(when.Match); if (when.Match == null) { SqlExpression @default = sql.Value(discriminator.GetType(), tc.Whens[0].Match.SqlType, defaultType.InheritanceCode, true, tc.SourceExpression); values.Add(@default); } else { // Must duplicate so that columnizer doesn't nominate the match as a value. values.Add(sql.Value(discriminator.GetType(), when.Match.SqlType, ((SqlValue)when.Match).Value, true, tc.SourceExpression)); } } return sql.Case(tc.Discriminator.ClrType, tc.Discriminator, matches, values, tc.SourceExpression); } else { var mt = this.model.GetMetaType(obj.ClrType).InheritanceRoot; if (mt.HasInheritance) { return this.VisitExpression(sql.Member(dof.Object, mt.Discriminator.Member)); } } return sql.TypedLiteralNull(dof.ClrType, dof.SourceExpression); }
internal override SqlExpression VisitDiscriminatorOf(SqlDiscriminatorOf dof) { return new SqlDiscriminatorOf(this.VisitExpression(dof.Object), dof.ClrType, dof.SqlType, dof.SourceExpression); }
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); } 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); } 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; } if(IsVbIIF(mc)) { return TranslateVbIIF(mc); } 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]); } 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; }