private static bool IsEquivalentTo(this IEdmPrimitiveType thisType, IEdmPrimitiveType otherType) { // ODataLib creates one-off instances of primitive type definitions that match by name and kind, but have different object refs. // So we can't use object ref comparison here like for other IEdmSchemaType objects. // See "src\Web\Client\System\Data\Services\Client\Serialization\PrimitiveType.cs:CreateEdmPrimitiveType()" for more info. return(thisType.PrimitiveKind == otherType.PrimitiveKind && thisType.FullName() == otherType.FullName()); }
private static bool IsEquivalentTo(this IEdmPrimitiveType thisType, IEdmPrimitiveType otherType) { if (thisType.PrimitiveKind != otherType.PrimitiveKind) { return(false); } else { return(thisType.FullName() == otherType.FullName()); } }
private static string GetTypeName(object value) { // Null values can be inferred, so we'd never call GetTypeName for them. Contract.Assert(value != null); Type valueType = value.GetType(); Contract.Assert(valueType != null); IEdmPrimitiveType primitiveType = EdmLibHelpers.GetEdmPrimitiveTypeOrNull(valueType); if (primitiveType == null) { throw new SerializationException(Error.Format(SRResources.UnsupportedPrimitiveType, valueType.FullName)); } string typeName = primitiveType.FullName(); Contract.Assert(typeName != null); return(typeName); }
internal Expression CreateBinaryExpression(BinaryOperatorKind binaryOperator, Expression left, Expression right, bool liftToNull) { ExpressionType binaryExpressionType; // When comparing an enum to a string, parse the string, convert both to the enum underlying type, and compare the values // When comparing an enum to an enum with the same type, convert both to the underlying type, and compare the values Type leftUnderlyingType = Nullable.GetUnderlyingType(left.Type) ?? left.Type; Type rightUnderlyingType = Nullable.GetUnderlyingType(right.Type) ?? right.Type; // Convert to integers unless Enum type is required if ((leftUnderlyingType.IsEnum || rightUnderlyingType.IsEnum) && binaryOperator != BinaryOperatorKind.Has) { Type enumType = leftUnderlyingType.IsEnum ? leftUnderlyingType : rightUnderlyingType; Type enumUnderlyingType = Enum.GetUnderlyingType(enumType); left = ConvertToEnumUnderlyingType(left, enumType, enumUnderlyingType); right = ConvertToEnumUnderlyingType(right, enumType, enumUnderlyingType); } if (leftUnderlyingType == typeof(DateTime) && rightUnderlyingType == typeof(DateTimeOffset)) { right = DateTimeOffsetToDateTime(right); } else if (rightUnderlyingType == typeof(DateTime) && leftUnderlyingType == typeof(DateTimeOffset)) { left = DateTimeOffsetToDateTime(left); } if ((IsDateOrOffset(leftUnderlyingType) && IsDate(rightUnderlyingType)) || (IsDate(leftUnderlyingType) && IsDateOrOffset(rightUnderlyingType))) { left = CreateDateBinaryExpression(left); right = CreateDateBinaryExpression(right); } if ((IsDateOrOffset(leftUnderlyingType) && IsTimeOfDay(rightUnderlyingType)) || (IsTimeOfDay(leftUnderlyingType) && IsDateOrOffset(rightUnderlyingType)) || (IsTimeSpan(leftUnderlyingType) && IsTimeOfDay(rightUnderlyingType)) || (IsTimeOfDay(leftUnderlyingType) && IsTimeSpan(rightUnderlyingType))) { left = CreateTimeBinaryExpression(left); right = CreateTimeBinaryExpression(right); } if (left.Type != right.Type) { // one of them must be nullable and the other is not. left = ToNullable(left); right = ToNullable(right); } if (left.Type == typeof(string) || right.Type == typeof(string)) { // convert nulls of type object to nulls of type string to make the String.Compare call work left = ConvertNull(left, typeof(string)); right = ConvertNull(right, typeof(string)); // Use string.Compare instead of comparison for gt, ge, lt, le between two strings since direct comparisons are not supported switch (binaryOperator) { case BinaryOperatorKind.GreaterThan: case BinaryOperatorKind.GreaterThanOrEqual: case BinaryOperatorKind.LessThan: case BinaryOperatorKind.LessThanOrEqual: left = Expression.Call(StringCompareMethodInfo, left, right, OrdinalStringComparisonConstant); right = ZeroConstant; break; default: break; } } if (BinaryOperatorMapping.TryGetValue(binaryOperator, out binaryExpressionType)) { if (left.Type == typeof(byte[]) || right.Type == typeof(byte[])) { left = ConvertNull(left, typeof(byte[])); right = ConvertNull(right, typeof(byte[])); switch (binaryExpressionType) { case ExpressionType.Equal: return(Expression.MakeBinary(binaryExpressionType, left, right, liftToNull, method: Linq2ObjectsComparisonMethods.AreByteArraysEqualMethodInfo)); case ExpressionType.NotEqual: return(Expression.MakeBinary(binaryExpressionType, left, right, liftToNull, method: Linq2ObjectsComparisonMethods.AreByteArraysNotEqualMethodInfo)); default: IEdmPrimitiveType binaryType = EdmLibHelpers.GetEdmPrimitiveTypeOrNull(typeof(byte[])); throw new ODataException(Error.Format(SRResources.BinaryOperatorNotSupported, binaryType.FullName(), binaryType.FullName(), binaryOperator)); } } else { return(Expression.MakeBinary(binaryExpressionType, left, right, liftToNull, method: null)); } } else { // Enum has a "has" operator // {(c1, c2) => c1.HasFlag(Convert(c2))} if (TypeHelper.IsEnum(left.Type) && TypeHelper.IsEnum(right.Type) && binaryOperator == BinaryOperatorKind.Has) { UnaryExpression flag = Expression.Convert(right, typeof(Enum)); return(BindHas(left, flag)); } else { throw Error.NotSupported(SRResources.QueryNodeBindingNotSupported, binaryOperator, typeof(FilterBinder).Name); } } }
private static object ConvertToTargetType(IEdmPrimitiveType targetEdmType, Func <object> converter) { try { return(converter()); } catch (OverflowException ex) { throw new ODataException(ODataErrorStrings.ODataUriUtils_ConvertFromUriLiteralOverflowNumber(targetEdmType.FullName(), ex.Message)); } }
private static bool IsEquivalentTo(this IEdmPrimitiveType thisType, IEdmPrimitiveType otherType) { // ODataLib creates one-off instances of primitive type definitions that match by name and kind, but have different object refs. // So we can't use object ref comparison here like for other IEdmSchemaType objects. // See "src\DataWeb\Client\System\Data\Services\Client\Serialization\PrimitiveType.cs:CreateEdmPrimitiveType()" for more info. return thisType.PrimitiveKind == otherType.PrimitiveKind && thisType.FullName() == otherType.FullName(); }
private static bool IsEquivalentTo(this IEdmPrimitiveType thisType, IEdmPrimitiveType otherType) { if (thisType.PrimitiveKind != otherType.PrimitiveKind) { return false; } else { return thisType.FullName() == otherType.FullName(); } }