SqlFactory.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Common / SqlFactory.cs / 1305376 / SqlFactory.cs

                            using System; 
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Linq.Expressions; 
using System.Data.Linq;
 
namespace System.Data.Linq.SqlClient { 
    using System.Data.Linq.Mapping;
    using System.Data.Linq.Provider; 
    using System.Diagnostics.CodeAnalysis;
    using System.Diagnostics;

    ///  
    /// Factory class produces SqlNodes. Smarts about type system mappings should go
    /// here and not in the individual SqlNodes. 
    ///  
    internal class SqlFactory {
        private TypeSystemProvider typeProvider; 
        private MetaModel model;

        internal TypeSystemProvider TypeProvider {
            get { return typeProvider; } 
        }
 
        internal SqlFactory(TypeSystemProvider typeProvider, MetaModel model) { 
            this.typeProvider = typeProvider;
            this.model = model; 
        }

        #region Expression Operators
 
        internal SqlExpression ConvertTo(Type clrType, ProviderType sqlType, SqlExpression expr) {
            return UnaryConvert(clrType, sqlType, expr, expr.SourceExpression); 
        } 

        internal SqlExpression ConvertTo(Type clrType, SqlExpression expr) { 
            //
            // In SQL Server 2008, the new TIME data type cannot be converted to BIGINT, or FLOAT,
            // or a bunch of other SQL types.
            // 
            if (clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(Nullable<>))
                clrType = clrType.GetGenericArguments()[0]; 
 
            bool isClrTimeSpanType = clrType == typeof(TimeSpan);
 
            if (IsSqlTimeType(expr))
            {
                if (isClrTimeSpanType) {
                    // no conversion necessary 
                    return expr;
                } else { 
                    expr = ConvertToDateTime(expr); 
                }
            } 

            return UnaryConvert(clrType, typeProvider.From(clrType), expr, expr.SourceExpression);
        }
 
        internal SqlExpression ConvertToBigint(SqlExpression expr) {
            return ConvertTo(typeof(long), expr); 
        } 

        internal SqlExpression ConvertToInt(SqlExpression expr) { 
            return ConvertTo(typeof(int), expr);
        }

        internal SqlExpression ConvertToDouble(SqlExpression expr) { 
            return ConvertTo(typeof(double), expr);
        } 
 
        // If the argument expression has SqlDbType Time, inject a conversion to Double, else return
        // the expression unchanged. 
        //
        internal SqlExpression ConvertTimeToDouble(SqlExpression exp) {
            return IsSqlTimeType(exp) ? ConvertToDouble(exp) : exp;
        } 

        internal SqlExpression ConvertToBool(SqlExpression expr) { 
            return ConvertTo(typeof(bool), expr); 
        }
 
        internal SqlExpression ConvertToDateTime(SqlExpression expr) {
            return UnaryConvert(typeof(DateTime), typeProvider.From(typeof(DateTime)), expr, expr.SourceExpression);
        }
 
        internal SqlExpression AndAccumulate(SqlExpression left, SqlExpression right) {
            if (left == null) { 
                return right; 
            }
            else if (right == null) { 
                return left;
            }
            else {
                return Binary(SqlNodeType.And, left, right); 
            }
        } 
 
        internal SqlExpression OrAccumulate(SqlExpression left, SqlExpression right) {
            if (left == null) { 
                return right;
            }
            else if (right == null) {
                return left; 
            }
            else { 
                return Binary(SqlNodeType.Or, left, right); 
            }
        } 

        internal SqlExpression Concat(params SqlExpression[] expressions) {
            SqlExpression result = expressions[expressions.Length - 1];
            for (int i = expressions.Length - 2; i >= 0; i--) { 
                result = Binary(SqlNodeType.Concat, expressions[i], result);
            } 
            return result; 
        }
 
        internal SqlExpression Add(params SqlExpression[] expressions) {
            SqlExpression sum = expressions[expressions.Length - 1];
            for (int i = expressions.Length - 2; i >= 0; i--) {
                sum = Binary(SqlNodeType.Add, expressions[i], sum); 
            }
            return sum; 
        } 

        internal SqlExpression Subtract(SqlExpression first, SqlExpression second) { 
            return Binary(SqlNodeType.Sub, first, second);
        }

        internal SqlExpression Multiply(params SqlExpression[] expressions) { 
            SqlExpression result = expressions[expressions.Length - 1];
            for (int i = expressions.Length - 2; i >= 0; i--) { 
                result = Binary(SqlNodeType.Mul, expressions[i], result); 
            }
            return result; 
        }

        internal SqlExpression Divide(SqlExpression first, SqlExpression second) {
            return Binary(SqlNodeType.Div, first, second); 
        }
 
        internal SqlExpression Add(SqlExpression expr, int second) { 
            return Binary(SqlNodeType.Add, expr, ValueFromObject(second, false, expr.SourceExpression));
        } 

        internal SqlExpression Subtract(SqlExpression expr, int second) {
            return Binary(SqlNodeType.Sub, expr, ValueFromObject(second, false, expr.SourceExpression));
        } 

        internal SqlExpression Multiply(SqlExpression expr, long second) { 
            return Binary(SqlNodeType.Mul, expr, ValueFromObject(second, false, expr.SourceExpression)); 
        }
 
        internal SqlExpression Divide(SqlExpression expr, long second) {
            return Binary(SqlNodeType.Div, expr, ValueFromObject(second, false, expr.SourceExpression));
        }
 
        internal SqlExpression Mod(SqlExpression expr, long second) {
            return Binary(SqlNodeType.Mod, expr, ValueFromObject(second, false, expr.SourceExpression)); 
        } 

        ///  
        /// Non-internal string length.  This should only be used when translating an explicit call by the
        /// user to String.Length.
        /// 
        internal SqlExpression LEN(SqlExpression expr) { 
            return FunctionCall(typeof(int), "LEN", new SqlExpression[] { expr }, expr.SourceExpression);
        } 
 
        /// 
        /// This represents the SQL DATALENGTH function, which is the raw number of bytes in the argument.  In the 
        /// case of string types it will count trailing spaces, but doesn't understand unicode.
        /// 
        internal SqlExpression DATALENGTH(SqlExpression expr) {
            return FunctionCall(typeof(int), "DATALENGTH", new SqlExpression[] { expr }, expr.SourceExpression); 
        }
 
        ///  
        /// A unary function that uses DATALENGTH, dividing by two if the string is unicode.  This is the internal
        /// form of String.Length that should always be used. 
        /// 
        internal SqlExpression CLRLENGTH(SqlExpression expr) {
            return Unary(SqlNodeType.ClrLength, expr);
        } 

        internal SqlExpression DATEPART(string partName, SqlExpression expr) { 
            return FunctionCall( 
                typeof(int),
                "DATEPART", 
                new SqlExpression[] {
                    new SqlVariable(typeof(void), null, partName, expr.SourceExpression),
                    expr
                }, 
                expr.SourceExpression
                ); 
        } 

        internal SqlExpression DATEADD(string partName, SqlExpression value, SqlExpression expr) { 
            return DATEADD(partName, value, expr, expr.SourceExpression, false);
        }

        internal SqlExpression DATEADD(string partName, SqlExpression value, SqlExpression expr, Expression sourceExpression, bool asNullable) { 
            Type returnType = asNullable ? typeof(DateTime?) : typeof(DateTime);
 
            return FunctionCall( 
                returnType,
                "DATEADD", 
                new SqlExpression[] {
                    new SqlVariable(typeof(void), null, partName, sourceExpression),
                    value,
                    expr }, 
                sourceExpression
                ); 
        } 

        internal SqlExpression DATETIMEOFFSETADD(string partName, SqlExpression value, SqlExpression expr) { 
            return DATETIMEOFFSETADD(partName, value, expr, expr.SourceExpression, false);
        }

        internal SqlExpression DATETIMEOFFSETADD(string partName, SqlExpression value, SqlExpression expr, Expression sourceExpression, bool asNullable) { 
            Type returnType = asNullable ? typeof(DateTimeOffset?) : typeof(DateTimeOffset);
 
            return FunctionCall( 
                returnType,
                "DATEADD", 
                new SqlExpression[] {
                    new SqlVariable(typeof(void), null, partName, sourceExpression),
                    value,
                    expr }, 
                sourceExpression
                ); 
        } 

        #endregion 

        internal SqlExpression AddTimeSpan(SqlExpression dateTime, SqlExpression timeSpan) {
            return AddTimeSpan(dateTime, timeSpan, false);
        } 

        internal SqlExpression AddTimeSpan(SqlExpression dateTime, SqlExpression timeSpan, bool asNullable) { 
            Debug.Assert(IsSqlHighPrecisionDateTimeType(timeSpan)); 

            SqlExpression ns = DATEPART("NANOSECOND", timeSpan); 
            SqlExpression ms = DATEPART("MILLISECOND", timeSpan);
            SqlExpression ss = DATEPART("SECOND", timeSpan);
            SqlExpression mi = DATEPART("MINUTE", timeSpan);
            SqlExpression hh = DATEPART("HOUR", timeSpan); 

            SqlExpression result = dateTime; 
            if (IsSqlHighPrecisionDateTimeType(dateTime)) { 
                result = DATEADD("NANOSECOND", ns, result, dateTime.SourceExpression, asNullable);
            } else { 
                result = DATEADD("MILLISECOND", ms, result, dateTime.SourceExpression, asNullable);
            }
            result = DATEADD("SECOND", ss, result, dateTime.SourceExpression, asNullable);
            result = DATEADD("MINUTE", mi, result, dateTime.SourceExpression, asNullable); 
            result = DATEADD("HOUR", hh, result, dateTime.SourceExpression, asNullable);
 
            if (IsSqlDateTimeOffsetType(dateTime)) 
                return ConvertTo(typeof(DateTimeOffset), result);
 
            return result;
        }

        internal static bool IsSqlDateTimeType(SqlExpression exp) { 
            SqlDbType sqlDbType = ((SqlTypeSystem.SqlType)(exp.SqlType)).SqlDbType;
            return (sqlDbType == SqlDbType.DateTime || sqlDbType == SqlDbType.SmallDateTime); 
        } 

        internal static bool IsSqlDateType(SqlExpression exp) { 
            return (((SqlTypeSystem.SqlType)(exp.SqlType)).SqlDbType == SqlDbType.Date);
        }

        internal static bool IsSqlTimeType(SqlExpression exp) { 
            return (((SqlTypeSystem.SqlType)(exp.SqlType)).SqlDbType == SqlDbType.Time);
        } 
 
        internal static bool IsSqlDateTimeOffsetType(SqlExpression exp) {
            return (((SqlTypeSystem.SqlType)(exp.SqlType)).SqlDbType == SqlDbType.DateTimeOffset); 
        }

        internal static bool IsSqlHighPrecisionDateTimeType(SqlExpression exp) {
            SqlDbType sqlDbType = ((SqlTypeSystem.SqlType)(exp.SqlType)).SqlDbType; 
            return (sqlDbType == SqlDbType.Time || sqlDbType == SqlDbType.DateTime2 || sqlDbType == SqlDbType.DateTimeOffset);
        } 
 
        internal SqlExpression Value(Type clrType, ProviderType sqlType, object value, bool isClientSpecified, Expression sourceExpression) {
            if (typeof(Type).IsAssignableFrom(clrType) && value != null) { 
                MetaType typeOf = this.model.GetMetaType((Type)value);
                return StaticType(typeOf, sourceExpression);
            }
            return new SqlValue(clrType, sqlType, value, isClientSpecified, sourceExpression); 
        }
 
        ///  
        /// Return a node representing typeof(typeOf)
        ///  
        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 SqlExpression DiscriminatedType(SqlExpression discriminator, MetaType targetType) {
            return new SqlDiscriminatedType(typeProvider.From(typeof(Type)), discriminator, targetType, discriminator.SourceExpression); 
        } 

        internal SqlTable Table(MetaTable table, MetaType rowType, Expression sourceExpression) { 
            return new SqlTable(table, rowType, this.typeProvider.GetApplicationType((int)ConverterSpecialTypes.Row), sourceExpression);
        }

        internal SqlUnary Unary(SqlNodeType nodeType, SqlExpression expression) { 
            return Unary(nodeType, expression, expression.SourceExpression);
        } 
 
        internal SqlRowNumber RowNumber(List orderBy, Expression sourceExpression) {
            return new SqlRowNumber(typeof(long), typeProvider.From(typeof(long)), orderBy, sourceExpression); 
        }

        internal SqlUnary Unary(SqlNodeType nodeType, SqlExpression expression, Expression sourceExpression) {
            return Unary(nodeType, expression, null, sourceExpression); 
        }
 
        internal SqlUnary Unary(SqlNodeType nodeType, SqlExpression expression, MethodInfo method, Expression sourceExpression) { 
            Type clrType = null;
            ProviderType sqlType = null; 

            if (nodeType == SqlNodeType.Count) {
                clrType = typeof(int);
                sqlType = typeProvider.From(typeof(int)); 
            }
            else if (nodeType == SqlNodeType.LongCount) { 
                clrType = typeof(long); 
                sqlType = typeProvider.From(typeof(long));
            } 
            else if (nodeType == SqlNodeType.ClrLength) {
                clrType = typeof(int);
                sqlType = typeProvider.From(typeof(int));
            } 
            else {
                if (nodeType.IsPredicateUnaryOperator()) { 
                    // DevDiv 201730 - Do not ignore nullability of bool type 
                    clrType = expression.ClrType.Equals(typeof(bool?)) ? typeof(bool?) : typeof(bool);
                } 
                else {
                    clrType = expression.ClrType;
                }
                sqlType = typeProvider.PredictTypeForUnary(nodeType, expression.SqlType); 
            }
 
            return new SqlUnary(nodeType, clrType, sqlType, expression, method, sourceExpression); 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")]
        internal SqlUnary UnaryConvert(Type targetClrType, ProviderType targetSqlType, SqlExpression expression, Expression sourceExpression) {
            System.Diagnostics.Debug.Assert(!targetSqlType.IsRuntimeOnlyType, "Attempted coversion to a runtime type: from = " + expression.SqlType.ToQueryString() + "; to = " + targetSqlType.ToQueryString() + "; source = " + sourceExpression.ToString());
            return new SqlUnary(SqlNodeType.Convert, targetClrType, targetSqlType, expression, null, sourceExpression); 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] 
        internal SqlUnary UnaryValueOf(SqlExpression expression, Expression sourceExpression) {
            Type valueType = TypeSystem.GetNonNullableType(expression.ClrType); 
            return new SqlUnary(SqlNodeType.ValueOf, valueType, expression.SqlType, expression, null, sourceExpression);
        }

        internal SqlBinary Binary(SqlNodeType nodeType, SqlExpression left, SqlExpression right) { 
            return Binary(nodeType, left, right, null, null);
        } 
 
        internal SqlBinary Binary(SqlNodeType nodeType, SqlExpression left, SqlExpression right, MethodInfo method) {
            return Binary(nodeType, left, right, method, null); 
        }

        internal SqlBinary Binary(SqlNodeType nodeType, SqlExpression left, SqlExpression right, Type clrType) {
            return Binary(nodeType, left, right, null, clrType); 
        }
 
        internal SqlBinary Binary(SqlNodeType nodeType, SqlExpression left, SqlExpression right, MethodInfo method, Type clrType) { 
            ProviderType sqlType = null;
            if (nodeType.IsPredicateBinaryOperator()) { 
                if (clrType == null) {
                    clrType = typeof(bool);
                }
                sqlType = typeProvider.From(clrType); 
            }
            else { 
                ProviderType resultType = this.typeProvider.PredictTypeForBinary(nodeType, left.SqlType, right.SqlType); 
                if (resultType == right.SqlType) {
                    if (clrType == null) { 
                        clrType = right.ClrType;
                    }
                    sqlType = right.SqlType;
                } 
                else if (resultType == left.SqlType) {
                    if (clrType == null) { 
                        clrType = left.ClrType; 
                    }
                    sqlType = left.SqlType; 
                }
                else {
                    sqlType = resultType;
                    if (clrType == null) { 
                        clrType = resultType.GetClosestRuntimeType();
                    } 
                } 
            }
            return new SqlBinary(nodeType, clrType, sqlType, left, right, method); 
        }

        internal SqlBetween Between(SqlExpression expr, SqlExpression start, SqlExpression end, Expression source) {
            return new SqlBetween(typeof(bool), typeProvider.From(typeof(bool)), expr, start, end, source); 
        }
 
        internal SqlIn In(SqlExpression expr, IEnumerable values, Expression source) { 
            return new SqlIn(typeof(bool), typeProvider.From(typeof(bool)), expr, values, source);
        } 

        internal SqlLike Like(SqlExpression expr, SqlExpression pattern, SqlExpression escape, Expression source) {
            SqlLike like = new SqlLike(typeof(bool), typeProvider.From(typeof(bool)), expr, pattern, escape, source);
            return like; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] 
        internal SqlSearchedCase SearchedCase(SqlWhen[] whens, SqlExpression @else, Expression sourceExpression) {
            return new SqlSearchedCase(whens[0].Value.ClrType, whens, @else, sourceExpression); 
        }

        /// 
        /// Construct either a SqlClientCase or a SqlSimpleCase depending on whether the individual cases 
        /// are client-aided or not.
        ///  
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] 
        internal SqlExpression Case(Type clrType, SqlExpression discriminator, List matches, List values, Expression sourceExpression) {
            if (values.Count == 0) { 
                throw Error.EmptyCaseNotSupported();
            }
            bool anyClient = false;
            foreach (SqlExpression value in values) { 
                anyClient |= value.IsClientAidedExpression();
            } 
            if (anyClient) { 
                List whens = new List();
                for (int i = 0, c = matches.Count; i < c; ++i) { 
                    whens.Add(new SqlClientWhen(matches[i], values[i]));
                }
                return new SqlClientCase(clrType, discriminator, whens, sourceExpression);
            } 
            else {
                List whens = new List(); 
                for (int i = 0, c = matches.Count; i < c; ++i) { 
                    whens.Add(new SqlWhen(matches[i], values[i]));
                } 
                return new SqlSimpleCase(clrType, discriminator, whens, sourceExpression);
            }
        }
 
        internal SqlExpression Parameter(object value, Expression source) {
            System.Diagnostics.Debug.Assert(value != null); 
            Type type = value.GetType(); 
            return Value(type, this.typeProvider.From(value), value, true, source);
        } 

        internal SqlExpression ValueFromObject(object value, Expression sourceExpression) {
            return ValueFromObject(value, false, sourceExpression);
        } 

        internal SqlExpression ValueFromObject(object value, bool isClientSpecified, Expression sourceExpression) { 
            if (value == null) { 
                System.Diagnostics.Debug.Assert(false);
                throw Error.ArgumentNull("value"); 
            }
            Type clrType = value.GetType();
            return ValueFromObject(value, clrType, isClientSpecified, sourceExpression);
        } 

        // Override allowing the CLR type of the value to be specified explicitly. 
        internal SqlExpression ValueFromObject(object value, Type clrType, bool isClientSpecified, Expression sourceExpression) { 
            if (clrType == null) {
                throw Error.ArgumentNull("clrType"); 
            }
            ProviderType sqlType = (value == null) ? this.typeProvider.From(clrType) : this.typeProvider.From(value);
            return Value(clrType, sqlType, value, isClientSpecified, sourceExpression);
        } 

        public SqlExpression TypedLiteralNull(Type type, Expression sourceExpression) { 
            return ValueFromObject(null, type, false, sourceExpression); 
        }
 
        internal SqlMember Member(SqlExpression expr, MetaDataMember member) {
            return new SqlMember(member.Type, this.Default(member), expr, member.Member);
        }
 
        internal SqlMember Member(SqlExpression expr, MemberInfo member) {
            Type clrType = TypeSystem.GetMemberType(member); 
            MetaType metaType = this.model.GetMetaType(member.DeclaringType); 
            MetaDataMember metaDataMember = metaType.GetDataMember(member);
            if (metaType != null && metaDataMember != null) { 
                return new SqlMember(clrType, this.Default(metaDataMember), expr, member);
            } else {
                return new SqlMember(clrType, this.Default(clrType), expr, member);
            } 
        }
 
        internal SqlExpression TypeCase(Type clrType, MetaType rowType, SqlExpression discriminator, IEnumerable whens, Expression sourceExpression) { 
            return new SqlTypeCase(clrType, typeProvider.From(clrType), rowType, discriminator, whens, sourceExpression);
        } 

        internal SqlNew New(MetaType type, ConstructorInfo cons, IEnumerable args, IEnumerable argMembers, IEnumerable bindings, Expression sourceExpression) {
            SqlNew tb = new SqlNew(type, typeProvider.From(type.Type), cons, args, argMembers, bindings, sourceExpression);
            return tb; 
        }
 
        internal SqlMethodCall MethodCall(MethodInfo method, SqlExpression obj, SqlExpression[] args, Expression sourceExpression) { 
            return new SqlMethodCall(method.ReturnType, this.Default(method.ReturnType), method, obj, args, sourceExpression);
        } 

        internal SqlMethodCall MethodCall(Type returnType, MethodInfo method, SqlExpression obj, SqlExpression[] args, Expression sourceExpression) {
            return new SqlMethodCall(returnType, this.Default(returnType), method, obj, args, sourceExpression);
        } 

        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] 
        internal SqlExprSet ExprSet(SqlExpression[] exprs, Expression sourceExpression) { 
            return new SqlExprSet(exprs[0].ClrType, exprs, sourceExpression);
        } 

        internal SqlSubSelect SubSelect(SqlNodeType nt, SqlSelect select) {
            return this.SubSelect(nt, select, null);
        } 
        internal SqlSubSelect SubSelect(SqlNodeType nt, SqlSelect select, Type clrType) {
            ProviderType sqlType = null; 
            switch (nt) { 
                case SqlNodeType.ScalarSubSelect:
                case SqlNodeType.Element: 
                    clrType = select.Selection.ClrType;
                    sqlType = select.Selection.SqlType;
                    break;
                case SqlNodeType.Multiset: 
                    if (clrType == null) {
                        clrType = typeof(List<>).MakeGenericType(select.Selection.ClrType); 
                    } 
                    sqlType = typeProvider.GetApplicationType((int)ConverterSpecialTypes.Table);
                    break; 
                case SqlNodeType.Exists:
                    clrType = typeof(bool);
                    sqlType = typeProvider.From(typeof(bool));
                    break; 
            }
            return new SqlSubSelect(nt, clrType, sqlType, select); 
        } 

        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] 
        internal SqlDoNotVisitExpression DoNotVisitExpression(SqlExpression expr) {
            return new SqlDoNotVisitExpression(expr);
        }
 
        internal SqlFunctionCall FunctionCall(Type clrType, string name, IEnumerable args, Expression source) {
            return new SqlFunctionCall(clrType, Default(clrType), name, args, source); 
        } 

        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] 
        internal SqlFunctionCall FunctionCall(Type clrType, ProviderType sqlType, string name, IEnumerable args, Expression source) {
            return new SqlFunctionCall(clrType, sqlType, name, args, source);
        }
 
        internal SqlTableValuedFunctionCall TableValuedFunctionCall(MetaType rowType, Type clrType, string name, IEnumerable args, Expression source) {
            return new SqlTableValuedFunctionCall(rowType, clrType, Default(clrType), name, args, source); 
        } 

        internal ProviderType Default(Type clrType) { 
            return typeProvider.From(clrType);
        }

        internal ProviderType Default(MetaDataMember member) { 
            if(member == null)
                throw Error.ArgumentNull("member"); 
 
            if (member.DbType != null) {
                return this.typeProvider.Parse(member.DbType); 
            }
            else {
                return this.typeProvider.From(member.Type);
            } 
        }
 
        internal SqlJoin MakeJoin(SqlJoinType joinType, SqlSource location, SqlAlias alias, SqlExpression condition, Expression source) { 
            // if the new item is on the right side of some outer join then fixup the projection to reflect that it can possibly be null
            if (joinType == SqlJoinType.LeftOuter) { 
                SqlSelect sel = alias.Node as SqlSelect;
                if (sel != null && sel.Selection != null && sel.Selection.NodeType != SqlNodeType.OptionalValue) {
                    // replace selection w/ optional + outer-joined-value
                    sel.Selection = new SqlOptionalValue( 
                                        new SqlColumn(
                                            "test", 
                                            this.Unary(SqlNodeType.OuterJoinedValue, 
                                                this.Value(typeof(int?), this.typeProvider.From(typeof(int)), 1, false, source))
                                            ), 
                                        sel.Selection
                                        );
                }
            } 
            return new SqlJoin(joinType, location, alias, condition, source);
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK