コード例 #1
0
        /// <summary>
        ///     Determines whether the node may be evaluated locally and whether
        ///     it is a constant. Assumes that all children are also client expressions.
        /// </summary>
        private bool IsImmutable(Expression expression)
        {
            if (null == expression)
            {
                return(false);
            }
            switch (expression.NodeType)
            {
            case ExpressionType.New:
            {
                // support construction of primitive types
                PrimitiveType primitiveType;
                if (!ClrProviderManifest.Instance.TryGetPrimitiveType(
                        TypeSystem.GetNonNullableType(expression.Type),
                        out primitiveType))
                {
                    return(false);
                }
                return(true);
            }

            case ExpressionType.Constant:
                return(true);

            case ExpressionType.NewArrayInit:
                // allow initialization of byte[] 'literals'
                return(typeof(byte[]) == expression.Type);

            case ExpressionType.Convert:
                return(true);

            default:
                return(false);
            }
        }
コード例 #2
0
        private bool IsImmutable(Expression expression)
        {
            if (expression == null)
            {
                return(false);
            }
            switch (expression.NodeType)
            {
            case ExpressionType.Constant:
                return(true);

            case ExpressionType.Convert:
                return(true);

            case ExpressionType.New:
                PrimitiveType primitiveType;
                return(ClrProviderManifest.Instance.TryGetPrimitiveType(TypeSystem.GetNonNullableType(expression.Type), out primitiveType));

            case ExpressionType.NewArrayInit:
                return(typeof(byte[]) == expression.Type);

            default:
                return(false);
            }
        }
コード例 #3
0
        // <summary>
        // Determine whether the given CLR type is legal for an ObjectParameter or constant
        // DbExpression.
        // </summary>
        private bool TryGetTypeUsageForTerminal(Expression expression, out TypeUsage typeUsage)
        {
            DebugCheck.NotNull(expression);

            var type = expression.Type;

            if (_rootContext.Perspective.TryGetTypeByName(
                    TypeSystem.GetNonNullableType(type).FullNameWithNesting(),
                    false, // bIgnoreCase
                    out typeUsage)
                &&
                (TypeSemantics.IsScalarType(typeUsage)))
            {
                if (expression.NodeType == ExpressionType.Convert)
                {
                    type = ((UnaryExpression)expression).Operand.Type;
                }

                if (type.IsValueType &&
                    Nullable.GetUnderlyingType(type) == null &&
                    TypeSemantics.IsNullable(typeUsage))
                {
                    typeUsage = typeUsage.ShallowCopy(
                        new FacetValues
                    {
                        Nullable = false
                    });
                }

                return(true);
            }

            typeUsage = null;
            return(false);
        }
コード例 #4
0
        // <summary>
        // Determine whether the given CLR type is legal for an ObjectParameter or constant
        // DbExpression.
        // </summary>
        private bool TryGetTypeUsageForTerminal(Type type, out TypeUsage typeUsage)
        {
            DebugCheck.NotNull(type);

            if (_rootContext.Perspective.TryGetTypeByName(
                    TypeSystem.GetNonNullableType(type).FullNameWithNesting(),
                    false, // bIgnoreCase
                    out typeUsage)
                &&
                (TypeSemantics.IsScalarType(typeUsage)))
            {
                if (type.IsValueType &&
                    Nullable.GetUnderlyingType(type) == null &&
                    TypeSemantics.IsNullable(typeUsage))
                {
                    typeUsage = typeUsage.ShallowCopy(
                        new FacetValues
                    {
                        Nullable = false
                    });
                }

                return(true);
            }

            typeUsage = null;
            return(false);
        }
コード例 #5
0
        /// <summary>
        ///     Determine whether the given CLR type is legal for an ObjectParameter or constant
        ///     DbExpression.
        /// </summary>
        private bool TryGetTypeUsageForTerminal(Type type, out TypeUsage typeUsage)
        {
            DebugCheck.NotNull(type);

            if (_rootContext.Perspective.TryGetTypeByName(
                    TypeSystem.GetNonNullableType(type).FullNameWithNesting(),
                    false, // bIgnoreCase
                    out typeUsage)
                &&
                (TypeSemantics.IsScalarType(typeUsage)))
            {
                return(true);
            }

            typeUsage = null;
            return(false);
        }
コード例 #6
0
        private bool TryGetTypeUsageForTerminal(Expression expression, out TypeUsage typeUsage)
        {
            Type type = expression.Type;

            if (this._rootContext.Perspective.TryGetTypeByName(TypeSystem.GetNonNullableType(type).FullNameWithNesting(), false, out typeUsage) && TypeSemantics.IsScalarType(typeUsage))
            {
                if (expression.NodeType == ExpressionType.Convert)
                {
                    type = ((UnaryExpression)expression).Operand.Type;
                }
                if (type.IsValueType && Nullable.GetUnderlyingType(type) == (Type)null && TypeSemantics.IsNullable(typeUsage))
                {
                    typeUsage = typeUsage.ShallowCopy(new FacetValues()
                    {
                        Nullable = (FacetValueContainer <bool?>) new bool?(false)
                    });
                }
                return(true);
            }
            typeUsage = (TypeUsage)null;
            return(false);
        }
コード例 #7
0
            internal static DbExpression ConvertToString(ExpressionConverter parent, LinqExpression linqExpression)
            {
                if (linqExpression.Type == typeof(object))
                {
                    var constantExpression = linqExpression as ConstantExpression;
                    linqExpression =
                        constantExpression != null?
                        Expression.Constant(constantExpression.Value) :
                            linqExpression.RemoveConvert();
                }

                var expression = parent.TranslateExpression(linqExpression);
                var clrType    = TypeSystem.GetNonNullableType(linqExpression.Type);

                if (clrType.IsEnum)
                {
                    //Flag enums are not supported.
                    if (Attribute.IsDefined(clrType, typeof(FlagsAttribute)))
                    {
                        throw new NotSupportedException(Strings.Elinq_ToStringNotSupportedForEnumsWithFlags);
                    }

                    if (linqExpression.IsNullConstant())
                    {
                        return(DbExpressionBuilder.Constant(string.Empty));
                    }

                    //Constant expression, optimize to constant name
                    if (linqExpression.NodeType == ExpressionType.Constant)
                    {
                        var value = ((ConstantExpression)linqExpression).Value;
                        var name  = Enum.GetName(clrType, value) ?? value.ToString();
                        return(DbExpressionBuilder.Constant(name));
                    }

                    var integralType = clrType.GetEnumUnderlyingType();
                    var type         = parent.GetValueLayerType(integralType);

                    var values = clrType.GetEnumValues()
                                 .Cast <object>()
                                 .Select(v => System.Convert.ChangeType(v, integralType, CultureInfo.InvariantCulture)) //cast to integral type so that unmapped enum types works too
                                 .Select(v => DbExpressionBuilder.Constant(v))
                                 .Select(c => (DbExpression)expression.CastTo(type).Equal(c))                           //cast expression to integral type before comparing to constant
                                 .Concat(new[] { expression.CastTo(type).IsNull() });                                   // default case

                    var names = clrType.GetEnumNames()
                                .Select(s => DbExpressionBuilder.Constant(s))
                                .Concat(new[] { DbExpressionBuilder.Constant(string.Empty) }); // default case

                    //translate unnamed enum values for the else clause, raw linq -> as integral value -> translate to cqt -> to string
                    //e.g.  ((DayOfWeek)99) -> "99"
                    var asIntegralLinq = LinqExpression.Convert(linqExpression, integralType);
                    var asStringCqt    = parent
                                         .TranslateExpression(asIntegralLinq)
                                         .CastTo(parent.GetValueLayerType(typeof(string)));

                    return(DbExpressionBuilder.Case(values, names, asStringCqt));
                }
                else if (TypeSemantics.IsPrimitiveType(expression.ResultType, PrimitiveTypeKind.String))
                {
                    return(StripNull(linqExpression, expression, expression));
                }
                else if (TypeSemantics.IsPrimitiveType(expression.ResultType, PrimitiveTypeKind.Guid))
                {
                    return(StripNull(linqExpression, expression, expression.CastTo(parent.GetValueLayerType(typeof(string))).ToLower()));
                }
                else if (TypeSemantics.IsPrimitiveType(expression.ResultType, PrimitiveTypeKind.Boolean))
                {
                    if (linqExpression.IsNullConstant())
                    {
                        return(DbExpressionBuilder.Constant(string.Empty));
                    }

                    if (linqExpression.NodeType == ExpressionType.Constant)
                    {
                        var name = ((ConstantExpression)linqExpression).Value.ToString();
                        return(DbExpressionBuilder.Constant(name));
                    }

                    var whenTrue  = expression.Equal(DbExpressionBuilder.True);
                    var whenFalse = expression.Equal(DbExpressionBuilder.False);
                    var thenTrue  = DbExpressionBuilder.Constant(true.ToString());
                    var thenFalse = DbExpressionBuilder.Constant(false.ToString());

                    return(DbExpressionBuilder.Case(
                               new[] { whenTrue, whenFalse },
                               new[] { thenTrue, thenFalse },
                               DbExpressionBuilder.Constant(string.Empty)));
                }
                else
                {
                    if (!SupportsCastToString(expression.ResultType))
                    {
                        throw new NotSupportedException(
                                  Strings.Elinq_ToStringNotSupportedForType(expression.ResultType.EdmType.Name));
                    }

                    //treat all other types as a simple cast
                    return(StripNull(linqExpression, expression, expression.CastTo(parent.GetValueLayerType(typeof(string)))));
                }
            }