Beispiel #1
0
        public SqlValueInputStream(SqlValue value, int startOffset)
        {
            if (value == null)
                throw new ArgumentNullException("value");

            this.value = value;
            position = startOffset;
            length = value.Length;
        }
 internal override SqlExpression VisitValue(SqlValue value) {
     if (!value.IsClientSpecified 
         && value.ClrType.IsClass 
         && value.ClrType != typeof(string) 
         && value.ClrType != typeof(Type) 
         && value.Value != null) {
         throw Error.ClassLiteralsNotAllowed(value.ClrType);
     }
     return value;
 }
Beispiel #3
0
        /// <summary>
        /// Visits the specified <see cref="SqlValue"/>.
        /// </summary>
        /// <param name="expression">
        /// The expression to visit.
        /// </param>
        public void Visit(SqlValue expression)
        {
            switch (expression.ExpressionType)
            {
                case SqlExpressionType.Column:
                    Visit((SqlColumn)expression);
                    break;

                case SqlExpressionType.Constant:
                    Visit((SqlConstant)expression);
                    break;

                case SqlExpressionType.Function:
                    Visit((SqlFunction)expression);
                    break;

                case SqlExpressionType.Parameter:
                    Visit((SqlParameter)expression);
                    break;

                case SqlExpressionType.ValueList:
                    Visit((SqlValueList)expression);
                    break;

                default:
                    throw new InvalidOperationException("Unknown type of expression found.");
            }
        }
Beispiel #4
0
        protected override void BuildLikePredicate(SelectQuery.Predicate.Like predicate)
        {
            if (predicate.Escape != null)
            {
                if (predicate.Expr2 is SqlValue && predicate.Escape is SqlValue)
                {
                    var text = ((SqlValue)predicate.Expr2).Value.ToString();
                    var val  = new SqlValue(ReescapeLikeText(text, (char)((SqlValue)predicate.Escape).Value));

                    predicate = new SelectQuery.Predicate.Like(predicate.Expr1, predicate.IsNot, val, null);
                }
                else if (predicate.Expr2 is SqlParameter)
                {
                    var p = (SqlParameter)predicate.Expr2;

                    if (p.LikeStart != null)
                    {
                        var value = (string)p.Value;

                        if (value != null)
                        {
                            value     = value.Replace("[", "[[]").Replace("~%", "[%]").Replace("~_", "[_]").Replace("~~", "[~]");
                            p         = new SqlParameter(p.SystemType, p.Name, value) { DbSize = p.DbSize, DataType = p.DataType, IsQueryParameter = p.IsQueryParameter };
                            predicate = new SelectQuery.Predicate.Like(predicate.Expr1, predicate.IsNot, p, null);
                        }
                    }
                }
            }

            base.BuildLikePredicate(predicate);
        }
		ISqlPredicate ParseEnumConversion(IParseContext context, Expression left, SqlQuery.Predicate.Operator op, Expression right)
		{
			UnaryExpression conv;
			Expression      value;

			if (left.NodeType == ExpressionType.Convert)
			{
				conv  = (UnaryExpression)left;
				value = right;
			}
			else
			{
				conv  = (UnaryExpression)right;
				value = left;
			}

			var operand = conv.Operand;
			var type    = operand.Type;

			if (!type.IsEnum)
				return null;

			var dic = new Dictionary<object, object>();

			var nullValue = MappingSchema.GetNullValue(type);

			if (nullValue != null)
				dic.Add(nullValue, null);

			var mapValues = MappingSchema.GetMapValues(type);

			if (mapValues != null)
				foreach (var mv in mapValues)
					if (!dic.ContainsKey(mv.OrigValue))
						dic.Add(mv.OrigValue, mv.MapValues[0]);

			if (dic.Count == 0)
				return null;

			switch (value.NodeType)
			{
				case ExpressionType.Constant:
					{
						var    origValue = Enum.Parse(type, Enum.GetName(type, ((ConstantExpression)value).Value), false);
						object mapValue;

						if (!dic.TryGetValue(origValue, out mapValue))
							return null;

						ISqlExpression l, r;

						if (left.NodeType == ExpressionType.Convert)
						{
							l = ParseExpression(context, operand);
							r = new SqlValue(mapValue);
						}
						else
						{
							r = ParseExpression(context, operand);
							l = new SqlValue(mapValue);
						}

						return Convert(context, new SqlQuery.Predicate.ExprExpr(l, op, r));
					}

				case ExpressionType.Convert:
					{
						value = ((UnaryExpression)value).Operand;

						var l = ParseExpression(context, operand);
						var r = ParseExpression(context, value);

						if (l is SqlParameter) ((SqlParameter)l).SetEnumConverter(type, MappingSchema);
						if (r is SqlParameter) ((SqlParameter)r).SetEnumConverter(type, MappingSchema);

						return Convert(context, new SqlQuery.Predicate.ExprExpr(l, op, r));
					}
			}

			return null;
		}
 internal override SqlExpression VisitValue(SqlValue value) {
     return value;
 }
Beispiel #7
0
 public SqlColumnValuePair(string columnName, object value)
 {
     this.Field = new DataField(columnName, value?.GetType());
     this.Value = new SqlValue(value);
 }
Beispiel #8
0
 private void GetChildProperty(object entity, PropertyInfo[] propertyInfos, object property, SqlColumn column, SqlValue val)
 {
     for (int n = 0; n < propertyInfos.Length; n++)
     {
         //A.B.C 最后一个C是属性,前面的是类
         var    classInfo       = column.Name.Split('.');
         string childFirstClass = classInfo[0];
         string childField      = classInfo[classInfo.Length - 1];
         object childValue      = GetValue(column, val);
         if (classInfo.Length > 2)
         {
             for (int m = 0; m < classInfo.Length - 1; m++)
             {
                 string childClass1 = classInfo[m];
                 if (propertyInfos[n].Name.ToLower() == childClass1.ToLower())
                 {
                     var childType        = propertyInfos[n].PropertyType;//myclass
                     var childEntityClass = childType.Assembly.CreateInstance(childType.FullName, true);
                     var popchilds        = childType.GetProperties(BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
                     propertyInfos[n].SetValue(entity, childEntityClass);
                     GetChildProperty(childEntityClass, popchilds, property, column, val);
                 }
             }
         }
         else
         {
             if (propertyInfos[n].Name.ToLower() == childFirstClass.ToLower())
             {
                 var childType        = propertyInfos[n].PropertyType;
                 var childEntityClass = childType.Assembly.CreateInstance(childType.FullName, true);
                 var popchilds        = childType.GetProperties(BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
                 var popchild         = popchilds.First(t => t.Name.ToLower() == childField.ToLower());
                 var emitSetter       = EmitHelper.CreatePropertiesFunc(popchilds);
                 popchild.SetValue(childEntityClass, childValue);
                 propertyInfos[n].SetValue(entity, childEntityClass);
             }
         }
     }
 }
Beispiel #9
0
            // Methods
            internal override SqlNode Visit(SqlNode node)
            {
                if (node == null)
                {
                    return(null);
                }
                sourceExpression = node as SqlExpression;
                if (sourceExpression != null)
                {
                    Type clrType = sourceExpression.ClrType;
                    for (UnwrapStack stack = UnwrapSequences; stack != null; stack = stack.Last)
                    {
                        if (stack.Unwrap)
                        {
                            clrType = TypeSystem.GetElementType(clrType);
                        }
                    }
                    sourceType = clrType;
                }
                if ((sourceType != null) && TypeSystem.GetNonNullableType(sourceType).IsValueType)
                {
                    return(node);
                }
                if ((sourceType != null) && TypeSystem.HasIEnumerable(sourceType))
                {
                    return(node);
                }
                switch (node.NodeType)
                {
                case SqlNodeType.ClientCase:
                case SqlNodeType.Convert:
                case SqlNodeType.DiscriminatedType:
                    return(node);

                case SqlNodeType.MethodCall:
                case SqlNodeType.Member:
                    return(node);

                case SqlNodeType.Link:
                    sourceType = ((SqlLink)node).RowType.Type;
                    return(node);

                case SqlNodeType.Element:
                case SqlNodeType.FunctionCall:
                    return(node);

                case SqlNodeType.ScalarSubSelect:
                case SqlNodeType.SearchedCase:
                    return(node);

                case SqlNodeType.New:
                    return(node);

                case SqlNodeType.Multiset:
                    return(node);

                case SqlNodeType.TypeCase:
                    sourceType = ((SqlTypeCase)node).RowType.Type;
                    return(node);

                case SqlNodeType.Value:
                {
                    SqlValue value2 = (SqlValue)node;
                    if (value2.Value != null)
                    {
                        sourceType = value2.Value.GetType();
                    }
                    return(node);
                }

                case SqlNodeType.SimpleCase:
                    return(node);

                case SqlNodeType.Table:
                    sourceType = ((SqlTable)node).RowType.Type;
                    return(node);
                }
                return(base.Visit(node));
            }
 private SqlParameter InsertLookup(SqlValue cp) {
     SqlParameterInfo pi = null;
     if (!this.map.TryGetValue(cp, out pi)) {
         SqlParameter p;
         if (this.timeProviderType == null) {
             p = new SqlParameter(cp.ClrType, cp.SqlType, this.parameterizer.CreateParameterName(), cp.SourceExpression);
             pi = new SqlParameterInfo(p, cp.Value);
         }
         else {
             p = new SqlParameter(cp.ClrType, this.timeProviderType, this.parameterizer.CreateParameterName(), cp.SourceExpression);
             pi = new SqlParameterInfo(p, ((DateTime)cp.Value).TimeOfDay);
         }
         this.map.Add(cp, pi);
         this.currentParams.Add(pi);
     }
     return pi.Parameter;
 }
Beispiel #11
0
 protected string FormattedValue()
 {
     return(Parameterize ?
            ParameterName :
            SqlValue.ValueString(FieldTemplate()));
 }
 internal override SqlExpression VisitValue(SqlValue value)
 {
     return(value);
 }
Beispiel #13
0
        /// <summary>
        /// Add a paremeter to the list, @ will be added to name automatically if not present
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void Add(string name, object value)
        {
            SqlValue val = new SqlValue(value);

            Add(new QueryParameter(FormatParameterName(name), val.Value));
        }
Beispiel #14
0
 internal SqlAssign(SqlColumn column, SqlValue value)
 {
     if (column == null) throw new ArgumentNullException(nameof(column));
     Column = column;
     Value = value ?? SqlConstant.Null;
 }
Beispiel #15
0
 public T2 Like(string expression, SqlValue escape)
 {
     return(Like(new SqlValue(expression), escape));
 }
Beispiel #16
0
 public SqlValueInputStream(SqlValue value)
     : this(value, 0)
 {
 }
Beispiel #17
0
 /// <summary>
 /// Creates a <see cref="SqlBinaryExpression"/> that represents an "less than" comparison.
 /// </summary>
 /// <param name="column">
 /// A <see cref="SqlColumn"/> to use as the left operand in the expression.
 /// </param>
 /// <param name="value">
 /// A <see cref="SqlValue"/> to use as the right operand in the expression.
 /// </param>
 /// <returns>
 /// A <see cref="SqlBinaryExpression"/> that represents an "less than" comparison between
 /// the value of the specified <paramref name="column"/> and the specified <paramref name="value"/>.
 /// </returns>
 /// <remarks>
 /// If you pass <see langword="null"/> for the <paramref name="value"/> argument, it
 /// will be automatically converted to <see cref="SqlConstant.Null"/>.
 /// </remarks>
 public static SqlBinaryExpression LessThan(SqlColumn column, SqlValue value)
 {
     return(new SqlBinaryExpression(column, SqlBinaryOperator.LessThan, value ?? SqlConstant.Null));
 }
Beispiel #18
0
            internal override SqlNode Visit(SqlNode node)
            {
                if (node == null)
                {
                    return(null);
                }

                sourceExpression = node as SqlExpression;
                if (sourceExpression != null)
                {
                    Type        type   = sourceExpression.ClrType;
                    UnwrapStack unwrap = this.UnwrapSequences;
                    while (unwrap != null)
                    {
                        if (unwrap.Unwrap)
                        {
                            type = TypeSystem.GetElementType(type);
                        }
                        unwrap = unwrap.Last;
                    }
                    sourceType = type;
                }
                if (sourceType != null && TypeSystem.GetNonNullableType(sourceType).IsValueType)
                {
                    return(node); // Value types can't also have a dynamic type.
                }
                if (sourceType != null && TypeSystem.HasIEnumerable(sourceType))
                {
                    return(node); // Sequences can't be polymorphic.
                }

                switch (node.NodeType)
                {
                case SqlNodeType.ScalarSubSelect:
                case SqlNodeType.Multiset:
                case SqlNodeType.Element:
                case SqlNodeType.SearchedCase:
                case SqlNodeType.ClientCase:
                case SqlNodeType.SimpleCase:
                case SqlNodeType.Member:
                case SqlNodeType.DiscriminatedType:
                case SqlNodeType.New:
                case SqlNodeType.FunctionCall:
                case SqlNodeType.MethodCall:
                case SqlNodeType.Convert:     // Object identity does not survive convert. It does survive Cast.
                    // Dig no further.
                    return(node);

                case SqlNodeType.TypeCase:
                    sourceType = ((SqlTypeCase)node).RowType.Type;
                    return(node);

                case SqlNodeType.Link:
                    sourceType = ((SqlLink)node).RowType.Type;
                    return(node);

                case SqlNodeType.Table:
                    sourceType = ((SqlTable)node).RowType.Type;
                    return(node);

                case SqlNodeType.Value:
                    SqlValue val = (SqlValue)node;
                    if (val.Value != null)
                    {
                        // In some cases the ClrType of a Value node may
                        // differ from the actual runtime type of the value.
                        // Therefore, we ensure here that the correct type is set.
                        sourceType = val.Value.GetType();
                    }
                    return(node);
                }
                return(base.Visit(node));
            }
 /// <summary>
 /// Return a node representing typeof(typeOf)
 /// </summary>
 internal SqlExpression StaticType(MetaType typeOf, Expression sourceExpression) {
     if (typeOf==null)
         throw Error.ArgumentNull("typeOf");
     if(typeOf.InheritanceCode==null) {
         // If no inheritance is involved, then there's no discriminator to 
         // make a discriminated type. In this case, just make a literal type.
         return new SqlValue(typeof(Type), this.typeProvider.From(typeof(Type)), typeOf.Type, false, sourceExpression);
     }
     Type type = typeOf.InheritanceCode.GetType();
     SqlValue match = new SqlValue(type, this.typeProvider.From(type), typeOf.InheritanceCode, true, sourceExpression);
     return this.DiscriminatedType(match, typeOf);
 }
 internal override SqlExpression VisitValue(SqlValue value) {
     if (this.topLevel || !value.IsClientSpecified || !value.SqlType.CanBeParameter) {
         return value;
     }
     else {
         return this.InsertLookup(value);
     }
 }
Beispiel #21
0
 /// <summary>
 /// Creates a <see cref="SqlBinaryExpression"/> that represents an equality comparison.
 /// </summary>
 /// <param name="column">
 /// A <see cref="SqlColumn"/> to use as the left operand in the expression.
 /// </param>
 /// <param name="value">
 /// A <see cref="SqlValue"/> to use as the right operand in the expression.
 /// </param>
 /// <returns>
 /// A <see cref="SqlBinaryExpression"/> that represents an equality comparison between
 /// the value of the specified <paramref name="column"/> and the specified <paramref name="value"/>.
 /// </returns>
 /// <remarks>
 /// If you pass <see langword="null"/> for the <paramref name="value"/> argument, it
 /// will be automatically converted to <see cref="SqlConstant.Null"/>.
 /// </remarks>
 public static SqlBinaryExpression Equal(SqlColumn column, SqlValue value)
 {
     return new SqlBinaryExpression(column, SqlBinaryOperator.Equal, value ?? SqlConstant.Null);
 }
Beispiel #22
0
 /// <summary>
 /// Creates a <see cref="SqlCast"/> that represents a conversion of the specified <paramref name="value"/>
 /// to the specified data type.
 /// </summary>
 /// <param name="value">
 /// The <see cref="SqlValue"/> to convert.
 /// </param>
 /// <param name="dataType">
 /// The <see cref="SqlDataType"/> to convert to.
 /// </param>
 /// <returns>
 /// A <see cref="SqlCast"/> that represents a conversion of the specified <paramref name="value"/>
 /// to the specified data type.
 /// </returns>
 public static SqlCast Cast(SqlValue value, SqlDataType dataType)
 {
     return(new SqlCast(value, dataType));
 }
 public ISqlSetClause Set(SqlColumn column, SqlValue value)
 {
     return(new SetClause(Parent, column, value));
 }
 internal virtual SqlExpression VisitValue(SqlValue value) {
     return value;
 }
Beispiel #25
0
 /// <summary>
 /// Creates a <see cref="SqlBinaryExpression"/> that represents an equality comparison.
 /// </summary>
 /// <param name="column">
 /// A <see cref="SqlColumn"/> to use as the left operand in the expression.
 /// </param>
 /// <param name="value">
 /// A <see cref="SqlValue"/> to use as the right operand in the expression.
 /// </param>
 /// <returns>
 /// A <see cref="SqlBinaryExpression"/> that represents an equality comparison between
 /// the value of the specified <paramref name="column"/> and the specified <paramref name="value"/>.
 /// </returns>
 /// <remarks>
 /// If you pass <see langword="null"/> for the <paramref name="value"/> argument, it
 /// will be automatically converted to <see cref="SqlConstant.Null"/>.
 /// </remarks>
 public static SqlBinaryExpression Equal(SqlColumn column, SqlValue value)
 {
     return(new SqlBinaryExpression(column, SqlBinaryOperator.Equal, value ?? SqlConstant.Null));
 }
Beispiel #26
0
 /// <summary>
 /// Creates a <see cref="SqlBinaryExpression"/> that represents an "greater than" comparison.
 /// </summary>
 /// <param name="column">
 /// A <see cref="SqlColumn"/> to use as the left operand in the expression.
 /// </param>
 /// <param name="value">
 /// A <see cref="SqlValue"/> to use as the right operand in the expression.
 /// </param>
 /// <returns>
 /// A <see cref="SqlBinaryExpression"/> that represents an "greater than" comparison between
 /// the value of the specified <paramref name="column"/> and the specified <paramref name="value"/>.
 /// </returns>
 /// <remarks>
 /// If you pass <see langword="null"/> for the <paramref name="value"/> argument, it
 /// will be automatically converted to <see cref="SqlConstant.Null"/>.
 /// </remarks>
 public static SqlBinaryExpression GreaterThan(SqlColumn column, SqlValue value)
 {
     return new SqlBinaryExpression(column, SqlBinaryOperator.GreaterThan, value ?? SqlConstant.Null);
 }
        internal override ProviderType ReturnTypeOfFunction(SqlFunctionCall functionCall)
        {
            var argumentTypes = this.GetArgumentTypes(functionCall);

            SqlType arg0 = (SqlType)argumentTypes[0];
            SqlType arg1 = argumentTypes.Length > 1 ? (SqlType)argumentTypes[1] : (SqlType)null;

            switch (functionCall.Name)
            {
            case "LEN":
            case "DATALENGTH":
                switch (arg0.SqlDbType)
                {
                case SqlDbType.NVarChar:
                case SqlDbType.VarChar:
                case SqlDbType.VarBinary:
                    if (arg0.IsLargeType)
                    {
                        return(SqlTypeSystem.Create(SqlDbType.BigInt));
                    }
                    else
                    {
                        return(SqlTypeSystem.Create(SqlDbType.Int));
                    }

                default:
                    return(SqlTypeSystem.Create(SqlDbType.Int));
                }

            case "ABS":
            case "SIGN":
            case "ROUND":
            case "CEILING":
            case "FLOOR":
            case "POWER":
                switch (arg0.SqlDbType)
                {
                case SqlDbType.TinyInt:
                case SqlDbType.Int:
                case SqlDbType.SmallInt:
                    return(SqlTypeSystem.Create(SqlDbType.Int));

                case SqlDbType.Float:
                case SqlDbType.Real:
                    return(SqlTypeSystem.Create(SqlDbType.Float));

                default:
                    return(arg0);
                }

            case "PATINDEX":
            case "CHARINDEX":
                if (arg1.IsLargeType)
                {
                    return(SqlTypeSystem.Create(SqlDbType.BigInt));
                }
                return(SqlTypeSystem.Create(SqlDbType.Int));

            case "SUBSTRING":
                if (functionCall.Arguments[2].NodeType == SqlNodeType.Value)
                {
                    SqlValue val = (SqlValue)functionCall.Arguments[2];

                    if (val.Value is int)
                    {
                        switch (arg0.SqlDbType)
                        {
                        case SqlDbType.NVarChar:
                        case SqlDbType.NChar:
                        case SqlDbType.VarChar:
                        case SqlDbType.Char:
                            return(SqlTypeSystem.Create(arg0.SqlDbType, (int)val.Value));

                        default:
                            return(null);
                        }
                    }
                }
                switch (arg0.SqlDbType)
                {
                case SqlDbType.NVarChar:
                case SqlDbType.NChar:
                    return(SqlTypeSystem.Create(SqlDbType.NVarChar));

                case SqlDbType.VarChar:
                case SqlDbType.Char:
                    return(SqlTypeSystem.Create(SqlDbType.VarChar));

                default:
                    return(null);
                }

            case "STUFF":
                // if the stuff call is an insertion  and is strictly additive
                // (no deletion of characters) the return type is the same as
                // a concatenation
                if (functionCall.Arguments.Count == 4)
                {
                    SqlValue delLength = functionCall.Arguments[2] as SqlValue;
                    if (delLength != null && (int)delLength.Value == 0)
                    {
                        return(PredictTypeForBinary(SqlNodeType.Concat,
                                                    functionCall.Arguments[0].SqlType, functionCall.Arguments[3].SqlType));
                    }
                }
                return(null);

            case "LOWER":
            case "UPPER":
            case "RTRIM":
            case "LTRIM":
            case "INSERT":
            case "REPLACE":
            case "LEFT":
            case "RIGHT":
            case "REVERSE":
                return(arg0);

            default:
                return(null);
            }
        }
		SqlValue BuildConstant(Expression expr)
		{
			SqlValue value;

			if (_constants.TryGetValue(expr, out value))
				return value;

			var lambda = Expression.Lambda<Func<object>>(Expression.Convert(expr, typeof(object)));

			var v = lambda.Compile()();

			if (v != null && v.GetType().IsEnum)
			{
				var attrs = v.GetType().GetCustomAttributes(typeof(SqlEnumAttribute), true);

				v = Map.EnumToValue(v, attrs.Length == 0);
			}

			value = new SqlValue(v);

			_constants.Add(expr, value);

			return value;
		}
Beispiel #29
0
        private SqlExpression ExpandTogether(List <SqlExpression> exprs)
        {
            switch (exprs[0].NodeType)
            {
            case SqlNodeType.MethodCall:
            {
                SqlMethodCall[] mcs = new SqlMethodCall[exprs.Count];
                for (int i = 0; i < mcs.Length; ++i)
                {
                    mcs[i] = (SqlMethodCall)exprs[i];
                }

                List <SqlExpression> expandedArgs = new List <SqlExpression>();

                for (int i = 0; i < mcs[0].Arguments.Count; ++i)
                {
                    List <SqlExpression> args = new List <SqlExpression>();
                    for (int j = 0; j < mcs.Length; ++j)
                    {
                        args.Add(mcs[j].Arguments[i]);
                    }
                    SqlExpression expanded = this.ExpandTogether(args);
                    expandedArgs.Add(expanded);
                }
                return(factory.MethodCall(mcs[0].Method, mcs[0].Object, expandedArgs.ToArray(), mcs[0].SourceExpression));
            }

            case SqlNodeType.ClientCase:
            {
                // Are they all the same?
                SqlClientCase[] scs = new SqlClientCase[exprs.Count];
                scs[0] = (SqlClientCase)exprs[0];
                for (int i = 1; i < scs.Length; ++i)
                {
                    scs[i] = (SqlClientCase)exprs[i];
                }

                // Expand expressions together.
                List <SqlExpression> expressions = new List <SqlExpression>();
                for (int i = 0; i < scs.Length; ++i)
                {
                    expressions.Add(scs[i].Expression);
                }
                SqlExpression expression = this.ExpandTogether(expressions);

                // Expand individual expressions together.
                List <SqlClientWhen> whens = new List <SqlClientWhen>();
                for (int i = 0; i < scs[0].Whens.Count; ++i)
                {
                    List <SqlExpression> scos = new List <SqlExpression>();
                    for (int j = 0; j < scs.Length; ++j)
                    {
                        SqlClientWhen when = scs[j].Whens[i];
                        scos.Add(when.Value);
                    }
                    whens.Add(new SqlClientWhen(scs[0].Whens[i].Match, this.ExpandTogether(scos)));
                }

                return(new SqlClientCase(scs[0].ClrType, expression, whens, scs[0].SourceExpression));
            }

            case SqlNodeType.TypeCase:
            {
                // Are they all the same?
                SqlTypeCase[] tcs = new SqlTypeCase[exprs.Count];
                tcs[0] = (SqlTypeCase)exprs[0];
                for (int i = 1; i < tcs.Length; ++i)
                {
                    tcs[i] = (SqlTypeCase)exprs[i];
                }

                // Expand discriminators together.
                List <SqlExpression> discriminators = new List <SqlExpression>();
                for (int i = 0; i < tcs.Length; ++i)
                {
                    discriminators.Add(tcs[i].Discriminator);
                }
                SqlExpression discriminator = this.ExpandTogether(discriminators);
                // Write expanded discriminators back in.
                for (int i = 0; i < tcs.Length; ++i)
                {
                    tcs[i].Discriminator = discriminators[i];
                }
                // Expand individual type bindings together.
                List <SqlTypeCaseWhen> whens = new List <SqlTypeCaseWhen>();
                for (int i = 0; i < tcs[0].Whens.Count; ++i)
                {
                    List <SqlExpression> scos = new List <SqlExpression>();
                    for (int j = 0; j < tcs.Length; ++j)
                    {
                        SqlTypeCaseWhen when = tcs[j].Whens[i];
                        scos.Add(when.TypeBinding);
                    }
                    SqlExpression expanded = this.ExpandTogether(scos);
                    whens.Add(new SqlTypeCaseWhen(tcs[0].Whens[i].Match, expanded));
                }

                return(factory.TypeCase(tcs[0].ClrType, tcs[0].RowType, discriminator, whens, tcs[0].SourceExpression));
            }

            case SqlNodeType.New:
            {
                // first verify all are similar client objects...
                SqlNew[] cobs = new SqlNew[exprs.Count];
                cobs[0] = (SqlNew)exprs[0];
                for (int i = 1, n = exprs.Count; i < n; i++)
                {
                    if (exprs[i] == null || exprs[i].NodeType != SqlNodeType.New)
                    {
                        throw Error.UnionIncompatibleConstruction();
                    }
                    cobs[i] = (SqlNew)exprs[1];
                    if (cobs[i].Members.Count != cobs[0].Members.Count)
                    {
                        throw Error.UnionDifferentMembers();
                    }
                    for (int m = 0, mn = cobs[0].Members.Count; m < mn; m++)
                    {
                        if (cobs[i].Members[m].Member != cobs[0].Members[m].Member)
                        {
                            throw Error.UnionDifferentMemberOrder();
                        }
                    }
                }
                SqlMemberAssign[] bindings = new SqlMemberAssign[cobs[0].Members.Count];
                for (int m = 0, mn = bindings.Length; m < mn; m++)
                {
                    List <SqlExpression> mexprs = new List <SqlExpression>();
                    for (int i = 0, n = exprs.Count; i < n; i++)
                    {
                        mexprs.Add(cobs[i].Members[m].Expression);
                    }
                    bindings[m] = new SqlMemberAssign(cobs[0].Members[m].Member, this.ExpandTogether(mexprs));
                    for (int i = 0, n = exprs.Count; i < n; i++)
                    {
                        cobs[i].Members[m].Expression = mexprs[i];
                    }
                }
                SqlExpression[] arguments = new SqlExpression[cobs[0].Args.Count];
                for (int m = 0, mn = arguments.Length; m < mn; ++m)
                {
                    List <SqlExpression> mexprs = new List <SqlExpression>();
                    for (int i = 0, n = exprs.Count; i < n; i++)
                    {
                        mexprs.Add(cobs[i].Args[m]);
                    }
                    arguments[m] = ExpandTogether(mexprs);
                }
                return(factory.New(cobs[0].MetaType, cobs[0].Constructor, arguments, cobs[0].ArgMembers, bindings, exprs[0].SourceExpression));
            }

            case SqlNodeType.Link:
            {
                SqlLink[] links = new SqlLink[exprs.Count];
                links[0] = (SqlLink)exprs[0];
                for (int i = 1, n = exprs.Count; i < n; i++)
                {
                    if (exprs[i] == null || exprs[i].NodeType != SqlNodeType.Link)
                    {
                        throw Error.UnionIncompatibleConstruction();
                    }
                    links[i] = (SqlLink)exprs[i];
                    if (links[i].KeyExpressions.Count != links[0].KeyExpressions.Count ||
                        links[i].Member != links[0].Member ||
                        (links[i].Expansion != null) != (links[0].Expansion != null))
                    {
                        throw Error.UnionIncompatibleConstruction();
                    }
                }
                SqlExpression[]      kexprs = new SqlExpression[links[0].KeyExpressions.Count];
                List <SqlExpression> lexprs = new List <SqlExpression>();
                for (int k = 0, nk = links[0].KeyExpressions.Count; k < nk; k++)
                {
                    lexprs.Clear();
                    for (int i = 0, n = exprs.Count; i < n; i++)
                    {
                        lexprs.Add(links[i].KeyExpressions[k]);
                    }
                    kexprs[k] = this.ExpandTogether(lexprs);
                    for (int i = 0, n = exprs.Count; i < n; i++)
                    {
                        links[i].KeyExpressions[k] = lexprs[i];
                    }
                }
                SqlExpression expansion = null;
                if (links[0].Expansion != null)
                {
                    lexprs.Clear();
                    for (int i = 0, n = exprs.Count; i < n; i++)
                    {
                        lexprs.Add(links[i].Expansion);
                    }
                    expansion = this.ExpandTogether(lexprs);
                    for (int i = 0, n = exprs.Count; i < n; i++)
                    {
                        links[i].Expansion = lexprs[i];
                    }
                }
                return(new SqlLink(links[0].Id, links[0].RowType, links[0].ClrType, links[0].SqlType, links[0].Expression, links[0].Member, kexprs, expansion, links[0].SourceExpression));
            }

            case SqlNodeType.Value:
            {
                /*
                 * ExprSet of all literals of the same value reduce to just a single literal.
                 */
                SqlValue val0 = (SqlValue)exprs[0];
                for (int i = 1; i < exprs.Count; ++i)
                {
                    SqlValue val = (SqlValue)exprs[i];
                    if (!Equals(val.Value, val0.Value))
                    {
                        return(this.ExpandIntoExprSet(exprs));
                    }
                }
                return(val0);
            }

            case SqlNodeType.OptionalValue:
            {
                if (exprs[0].SqlType.CanBeColumn)
                {
                    goto default;
                }
                List <SqlExpression> hvals = new List <SqlExpression>(exprs.Count);
                List <SqlExpression> vals  = new List <SqlExpression>(exprs.Count);
                for (int i = 0, n = exprs.Count; i < n; i++)
                {
                    if (exprs[i] == null || exprs[i].NodeType != SqlNodeType.OptionalValue)
                    {
                        throw Error.UnionIncompatibleConstruction();
                    }
                    SqlOptionalValue sov = (SqlOptionalValue)exprs[i];
                    hvals.Add(sov.HasValue);
                    vals.Add(sov.Value);
                }
                return(new SqlOptionalValue(this.ExpandTogether(hvals), this.ExpandTogether(vals)));
            }

            case SqlNodeType.OuterJoinedValue:
            {
                if (exprs[0].SqlType.CanBeColumn)
                {
                    goto default;
                }
                List <SqlExpression> values = new List <SqlExpression>(exprs.Count);
                for (int i = 0, n = exprs.Count; i < n; i++)
                {
                    if (exprs[i] == null || exprs[i].NodeType != SqlNodeType.OuterJoinedValue)
                    {
                        throw Error.UnionIncompatibleConstruction();
                    }
                    SqlUnary su = (SqlUnary)exprs[i];
                    values.Add(su.Operand);
                }
                return(factory.Unary(SqlNodeType.OuterJoinedValue, this.ExpandTogether(values)));
            }

            case SqlNodeType.DiscriminatedType:
            {
                SqlDiscriminatedType sdt0 = (SqlDiscriminatedType)exprs[0];
                List <SqlExpression> foos = new List <SqlExpression>(exprs.Count);
                foos.Add(sdt0.Discriminator);
                for (int i = 1, n = exprs.Count; i < n; i++)
                {
                    SqlDiscriminatedType sdtN = (SqlDiscriminatedType)exprs[i];
                    if (sdtN.TargetType != sdt0.TargetType)
                    {
                        throw Error.UnionIncompatibleConstruction();
                    }
                    foos.Add(sdtN.Discriminator);
                }
                return(factory.DiscriminatedType(this.ExpandTogether(foos), ((SqlDiscriminatedType)exprs[0]).TargetType));
            }

            case SqlNodeType.ClientQuery:
            case SqlNodeType.Multiset:
            case SqlNodeType.Element:
            case SqlNodeType.Grouping:
                throw Error.UnionWithHierarchy();

            default:
                return(this.ExpandIntoExprSet(exprs));
            }
        }
		public override ISqlPredicate ConvertPredicate(ISqlPredicate predicate)
		{
			if (predicate is SqlQuery.Predicate.Like)
			{
				var l = (SqlQuery.Predicate.Like)predicate;

				if (l.Escape != null)
				{
					if (l.Expr2 is SqlValue && l.Escape is SqlValue)
					{
						var text = ((SqlValue) l.Expr2).Value.ToString();
						var val  = new SqlValue(ReescapeLikeText(text, (char)((SqlValue)l.Escape).Value));

						return new SqlQuery.Predicate.Like(l.Expr1, l.IsNot, val, null);
					}

					if (l.Expr2 is SqlParameter)
					{
						var p = (SqlParameter)l.Expr2;
						var v = "";
						
						if (p.ValueConverter != null)
							v = p.ValueConverter(" ") as string;

						p.SetLikeConverter(v.StartsWith("%") ? "%" : "", v.EndsWith("%") ? "%" : "");

						return new SqlQuery.Predicate.Like(l.Expr1, l.IsNot, p, null);
					}
				}
			}

			return base.ConvertPredicate(predicate);
		}
            void Init()
            {
                var info1 = _sequence1.ConvertToIndex(null, 0, ConvertFlags.All).ToList();
                var info2 = _sequence2.ConvertToIndex(null, 0, ConvertFlags.All).ToList();

                if (!_isObject)
                {
                    return;
                }

                var unionMembers = new List <UnionMember>();

                foreach (var info in info1)
                {
                    if (info.MemberChain.Count == 0)
                    {
                        throw new InvalidOperationException();
                    }

                    var mi = info.MemberChain.First(m => m.DeclaringType.IsSameOrParentOf(_unionParameter !.Type));

                    var member = new Member
                    {
                        SequenceInfo     = info,
                        MemberExpression = Expression.MakeMemberAccess(_unionParameter, mi)
                    };

                    unionMembers.Add(new UnionMember {
                        Member = member, Info1 = info
                    });
                }

                foreach (var info in info2)
                {
                    if (info.MemberChain.Count == 0)
                    {
                        throw new InvalidOperationException();
                    }

                    var em = unionMembers.FirstOrDefault(m =>
                                                         m.Member.SequenceInfo != null &&
                                                         m.Info2 == null &&
                                                         m.Member.SequenceInfo.CompareMembers(info));

                    if (em == null)
                    {
                        em = unionMembers.FirstOrDefault(m =>
                                                         m.Member.SequenceInfo != null &&
                                                         m.Info2 == null &&
                                                         m.Member.SequenceInfo.CompareLastMember(info));
                    }

                    if (em == null)
                    {
                        var member = new Member {
                            MemberExpression = Expression.MakeMemberAccess(_unionParameter, info.MemberChain[0])
                        };

                        if (_sequence2.IsExpression(member.MemberExpression, 1, RequestFor.Object).Result)
                        {
                            throw new LinqException("Types in {0} are constructed incompatibly.", _methodCall.Method.Name);
                        }

                        unionMembers.Add(new UnionMember {
                            Member = member, Info2 = info
                        });
                    }
                    else
                    {
                        em.Info2 = info;
                    }
                }

                var aliases1 = _sequence1.SelectQuery.Select.Columns.ToLookup(c => c.Expression, c => c.Alias);
                var aliases2 = _sequence2.SelectQuery.Select.Columns.ToLookup(c => c.Expression, c => c.Alias);

                _sequence1.SelectQuery.Select.Columns.Clear();
                _sequence2.SelectQuery.Select.Columns.Clear();

                for (var i = 0; i < unionMembers.Count; i++)
                {
                    var member = unionMembers[i];

                    if (member.Info1 == null)
                    {
                        var type = unionMembers.First(m => m.Info1 != null).Info1 !.MemberChain.First().GetMemberType();
                        member.Info1 = new SqlInfo(member.Info2 !.MemberChain)
                        {
                            Sql   = new SqlValue(type, null),
                            Query = _sequence1.SelectQuery,
                        };

                        member.Member.SequenceInfo = member.Info1;
                    }

                    if (member.Info2 == null)
                    {
                        var spam = unionMembers.First(m => m.Info2 != null).Info2 !.MemberChain.First();
                        var type = spam.GetMemberType();

                        member.Info2 = new SqlInfo(member.Info1.MemberChain)
                        {
                            Sql   = new SqlValue(type, null),
                            Query = _sequence2.SelectQuery,
                        };
                    }
 internal override SqlExpression VisitValue(SqlValue value) {
     if (value.IsClientSpecified && !this.isDebugMode) {
         throw Error.InvalidFormatNode("Value");
     }
     else {
         this.FormatValue(value.Value);
     }
     return value;
 }
 internal override SqlExpression VisitBinaryOperator(SqlBinary bo) {
     if (IsCompareToValue(bo)) {
         SqlMethodCall call = (SqlMethodCall)bo.Left;
         if (IsCompareToMethod(call)) {
             int iValue = System.Convert.ToInt32(this.Eval(bo.Right), Globalization.CultureInfo.InvariantCulture);
             bo = this.MakeCompareTo(call.Object, call.Arguments[0], bo.NodeType, iValue) ?? bo;
         }
         else if (IsCompareMethod(call)) {
             int iValue = System.Convert.ToInt32(this.Eval(bo.Right), Globalization.CultureInfo.InvariantCulture);
             bo = this.MakeCompareTo(call.Arguments[0], call.Arguments[1], bo.NodeType, iValue) ?? bo;
         }
     }
     else if (IsVbCompareStringEqualsValue(bo)) {
         SqlMethodCall call = (SqlMethodCall)bo.Left;
         int iValue = System.Convert.ToInt32(this.Eval(bo.Right), Globalization.CultureInfo.InvariantCulture);
         //in VB, comparing a string with Nothing means comparing with ""
         SqlValue strValue = call.Arguments[1] as SqlValue;
         if (strValue != null && strValue.Value == null) {
             SqlValue emptyStr = new SqlValue(strValue.ClrType, strValue.SqlType, String.Empty, strValue.IsClientSpecified, strValue.SourceExpression);
             bo = this.MakeCompareTo(call.Arguments[0], emptyStr, bo.NodeType, iValue) ?? bo;
         }
         else {
             bo = this.MakeCompareTo(call.Arguments[0], call.Arguments[1], bo.NodeType, iValue) ?? bo;
         }
     }
     return base.VisitBinaryOperator(bo);
 }
 private SqlExpression CoerceValueForExpression(SqlValue value, SqlExpression expression)
 {
     object clrValue = value.Value;
     if (!value.ClrType.IsAssignableFrom(expression.ClrType)) {
         clrValue = DBConvert.ChangeType(clrValue, expression.ClrType);
     }
     ProviderType newSqlType = typeProvider.ChangeTypeFamilyTo(value.SqlType, expression.SqlType);
     return sql.Value(expression.ClrType, newSqlType, clrValue, value.IsClientSpecified, value.SourceExpression);
 }
Beispiel #35
0
        protected override void BuildLikePredicate(SqlPredicate.Like predicate)
        {
            if (predicate.Expr2 is SqlValue)
            {
                var value = ((SqlValue)predicate.Expr2).Value;

                if (value != null)
                {
                    var text = ((SqlValue)predicate.Expr2).Value.ToString();

                    var ntext = predicate.IsSqlLike ? text : DataTools.EscapeUnterminatedBracket(text);

                    if (text != ntext)
                    {
                        predicate = new SqlPredicate.Like(predicate.Expr1, predicate.IsNot, new SqlValue(ntext), predicate.Escape, predicate.IsSqlLike);
                    }
                }
            }
            else if (predicate.Expr2 is SqlParameter)
            {
                var p = ((SqlParameter)predicate.Expr2);
                p.ReplaceLike = predicate.IsSqlLike != true;
            }

            if (predicate.Escape != null)
            {
                if (predicate.Expr2 is SqlValue && predicate.Escape is SqlValue)
                {
                    var value = ((SqlValue)predicate.Expr2).Value;

                    if (value != null)
                    {
                        var text = ((SqlValue)predicate.Expr2).Value.ToString();
                        var val  = new SqlValue(ReescapeLikeText(text, (char)((SqlValue)predicate.Escape).Value));

                        predicate = new SqlPredicate.Like(predicate.Expr1, predicate.IsNot, val, null, predicate.IsSqlLike);
                    }
                }
                else if (predicate.Expr2 is SqlParameter)
                {
                    var p = (SqlParameter)predicate.Expr2;

                    if (p.LikeStart != null)
                    {
                        var value = (string)p.Value;

                        if (value != null)
                        {
                            value = (predicate.IsSqlLike ? value : DataTools.EscapeUnterminatedBracket(value))
                                    .Replace("~%", "[%]").Replace("~_", "[_]").Replace("~~", "[~]");
                            p = new SqlParameter(p.SystemType, p.Name, value)
                            {
                                DbSize = p.DbSize, DataType = p.DataType, IsQueryParameter = p.IsQueryParameter, DbType = p.DbType
                            };
                            predicate = new SqlPredicate.Like(predicate.Expr1, predicate.IsNot, p, null, predicate.IsSqlLike);
                        }
                    }
                }
            }

            base.BuildLikePredicate(predicate);
        }