/// <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); } }
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); } }
// <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); }
// <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); }
/// <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); }
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); }
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))))); } }