public void IFTypeProperty_HasNoKeyAttribute_TypeIsNotEntity()
        {
            //Arrange
            Type student = typeof(Student);
            //Act
            bool actualResult = ClientTypeUtil.TypeOrElementTypeIsEntity(student);

            //Assert
            Assert.False(actualResult);
        }
        /// <summary>
        /// Returns true the specified entry represents an entity.
        /// </summary>
        /// <param name="entity">The resolved instance</param>
        /// <param name="model">The client model.</param>
        /// <returns>True if the entry represents an entity.</returns>
        private static bool IsEntity(object entity, ClientEdmModel model)
        {
            if (entity == null)
            {
                // you can set link to null, we need to track these values
                return(true);
            }

            return(ClientTypeUtil.TypeIsEntity(entity.GetType(), model));
        }
        public void IFTypeProperty_HasKeyAttribute_TypeIsEntity()
        {
            //Arrange
            Type person = typeof(Person);
            //Act
            bool actualResult = ClientTypeUtil.TypeOrElementTypeIsEntity(person);

            //Assert
            Assert.True(actualResult);
        }
            internal override Expression VisitBinary(BinaryExpression b)
            {
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(b.Left.Type) ||
                    ClientTypeUtil.TypeOrElementTypeIsEntity(b.Right.Type) ||
                    IsCollectionProducingExpression(b.Left) || IsCollectionProducingExpression(b.Right))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, b.ToString()));
                }

                return(base.VisitBinary(b));
            }
            internal override Expression VisitInvocation(InvocationExpression iv)
            {
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(iv.Expression.Type) ||
                    IsCollectionProducingExpression(iv.Expression) ||
                    iv.Arguments.Any(a => ClientTypeUtil.TypeOrElementTypeIsEntity(a.Type) || IsCollectionProducingExpression(a)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, iv.ToString()));
                }

                return(base.VisitInvocation(iv));
            }
            internal override NewExpression VisitNew(NewExpression nex)
            {
                // Allow creation of DataServiceCollection<T> objects in projections, stop others that project entities
                if (ClientTypeUtil.TypeOrElementTypeIsEntity(nex.Type) &&
                    !ResourceBinder.PatternRules.MatchNewDataServiceCollectionOfT(nex))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, nex.ToString()));
                }

                return(base.VisitNew(nex));
            }
Example #7
0
 private static void Analyze(MemberInitExpression mie, PathBox pb, DataServiceContext context)
 {
     if (ClientTypeUtil.TypeOrElementTypeIsEntity(mie.Type))
     {
         EntityProjectionAnalyzer.Analyze(mie, pb, context);
     }
     else
     {
         NonEntityProjectionAnalyzer.Analyze(mie, pb, context);
     }
 }
        public void IFTypeProperty_HasKeyAttributeAndOneProperty_TypeIsEntityAndDoesNotThrowException()
        {
            //Arrange
            Type car = typeof(Car);

            //Act
            bool actualResult = ClientTypeUtil.TypeOrElementTypeIsEntity(car);

            //Assert
            Assert.True(actualResult);
        }
            internal override Expression VisitMemberInit(MemberInitExpression init)
            {
                if (!ClientTypeUtil.TypeOrElementTypeIsEntity(init.Type))
                {
                    // MemberInit to a complex type is not supported on entity types.
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, init.ToString()));
                }

                ProjectionAnalyzer.Analyze(init, this.builder, this.context);
                return(init);
            }
Example #10
0
        /// <summary>
        /// Reads a value from the message reader.
        /// </summary>
        /// <param name="expectedClientType">The expected client type being materialized into.</param>
        /// <param name="expectedReaderType">The expected type for the underlying reader.</param>
        protected override void ReadWithExpectedType(IEdmTypeReference expectedClientType, IEdmTypeReference expectedReaderType)
        {
            ODataProperty property = this.messageReader.ReadProperty(expectedReaderType);
            Type          underlyingExpectedType = Nullable.GetUnderlyingType(this.ExpectedType) ?? this.ExpectedType;

            object propertyValue = property.Value;

            if (expectedClientType.IsCollection())
            {
                Debug.Assert(WebUtil.IsCLRTypeCollection(underlyingExpectedType, this.MaterializerContext.Model) || (SingleResult.HasValue && !SingleResult.Value), "expected type must be collection or single result must be false");

                // We are here for two cases:
                // (1) Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
                // (2) Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
                Type   collectionItemType        = underlyingExpectedType;
                Type   collectionICollectionType = ClientTypeUtil.GetImplementationType(underlyingExpectedType, typeof(ICollection <>));
                object collectionInstance;

                if (collectionICollectionType != null)
                {
                    // Case 1
                    collectionItemType = collectionICollectionType.GetGenericArguments()[0];
                    collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionPropertyInstance(property, underlyingExpectedType);
                }
                else
                {
                    // Case 2
                    collectionICollectionType = typeof(ICollection <>).MakeGenericType(new Type[] { collectionItemType });
                    collectionInstance        = this.CollectionValueMaterializationPolicy.CreateCollectionPropertyInstance(property, collectionICollectionType);
                }

                this.CollectionValueMaterializationPolicy.ApplyCollectionDataValues(
                    property,
                    collectionInstance,
                    collectionItemType,
                    ClientTypeUtil.GetAddToCollectionDelegate(collectionICollectionType));

                this.currentValue = collectionInstance;
            }
            else if (expectedClientType.IsComplex())
            {
                ODataComplexValue complexValue = propertyValue as ODataComplexValue;
                Debug.Assert(this.MaterializerContext.Model.GetOrCreateEdmType(underlyingExpectedType).ToEdmTypeReference(false).IsComplex(), "expectedType must be complex type");

                this.ComplexValueMaterializationPolicy.MaterializeComplexTypeProperty(underlyingExpectedType, complexValue);
                this.currentValue = complexValue.GetMaterializedValue();
            }
            else
            {
                Debug.Assert(this.MaterializerContext.Model.GetOrCreateEdmType(underlyingExpectedType).ToEdmTypeReference(false).IsPrimitive(), "expectedType must be primitive type");
                this.currentValue = this.PrimitivePropertyConverter.ConvertPrimitiveValue(property.Value, this.ExpectedType);
            }
        }
Example #11
0
        internal void EnterLambdaScope(LambdaExpression lambda, Expression entry, Expression expectedType)
        {
            ParameterExpression item = lambda.Parameters[0];
            Type type = lambda.Body.Type;
            bool flag = ClientTypeUtil.TypeOrElementTypeIsEntity(type);

            this.entityInScope.Push(flag);
            this.parameterExpressions.Push(item);
            this.parameterExpressionTypes.Push(expectedType);
            this.parameterEntries.Push(entry);
            this.parameterProjectionTypes.Push(type);
        }
Example #12
0
 internal override Expression VisitParameter(ParameterExpression p)
 {
     if (ClientTypeUtil.TypeOrElementTypeIsEntity(p.Type))
     {
         if (p != this.box.ParamExpressionInScope)
         {
             throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, p.ToString()));
         }
         this.box.StartNewPath();
     }
     return(p);
 }
Example #13
0
        /// <summary>
        /// ConstantExpression visit method
        /// </summary>
        /// <param name="c">The ConstantExpression expression to visit</param>
        /// <returns>The visited ConstantExpression expression </returns>
        internal override Expression VisitConstant(ConstantExpression c)
        {
            if (c.Value == null)
            {
                this.builder.Append(UriHelper.NULL);
                return(c);
            }

            // DEVNOTE:
            // Rather than forcing every other codepath to have the 'Try...' pattern for formatting,
            // we catch the InvalidOperationException here to change the exception type.
            // This is exceedingly rare, and not a scenario where performance is meaningful, so the
            // reduced complexity in all other call sites is worth the extra logic here.
            string               result;
            BinaryExpression     b = this.parent as BinaryExpression;
            MethodCallExpression m = this.parent as MethodCallExpression;

            if ((b != null && HasEnumInBinaryExpression(b)) || (m != null && m.Method.Name == "HasFlag"))
            {
                c = this.ConvertConstantExpressionForEnum(c);
                ClientEdmModel       model          = this.context.Model;
                IEdmType             edmType        = model.GetOrCreateEdmType(c.Type.IsEnum() ? c.Type : c.Type.GetGenericArguments()[0]);
                ClientTypeAnnotation typeAnnotation = model.GetClientTypeAnnotation(edmType);
                string         typeNameInEdm        = this.context.ResolveNameFromTypeInternal(typeAnnotation.ElementType);
                MemberInfo     member      = typeAnnotation.ElementType.GetField(c.Value.ToString());
                string         memberValue = ClientTypeUtil.GetServerDefinedName(member);
                ODataEnumValue enumValue   = new ODataEnumValue(memberValue, typeNameInEdm ?? typeAnnotation.ElementTypeName);
                result = ODataUriUtils.ConvertToUriLiteral(enumValue, CommonUtil.ConvertToODataVersion(this.uriVersion), null);
            }
            else
            {
                try
                {
                    result = LiteralFormatter.ForConstants.Format(c.Value);
                }
                catch (InvalidOperationException)
                {
                    if (this.cantTranslateExpression)
                    {
                        // there's already a problem in the parents.
                        // we should just return here, because caller somewhere up the stack will throw a better exception
                        return(c);
                    }

                    throw new NotSupportedException(Strings.ALinq_CouldNotConvert(c.Value));
                }
            }

            Debug.Assert(result != null, "result != null");
            this.builder.Append(result);
            return(c);
        }
Example #14
0
        public void ShouldMaterializeTimeOfDayCollection()
        {
            var primitiveValues  = new List <TimeOfDay>(new TimeOfDay[] { TimeOfDay.MinValue, new TimeOfDay(19, 9, 28, 123), TimeOfDay.MaxValue });
            var outputCollection = new List <TimeOfDay>();
            var addToDelegate    = ClientTypeUtil.GetAddToCollectionDelegate(outputCollection.GetType());

            this.CreateCollectionValueMaterializationPolicy().ApplyCollectionDataValues(
                primitiveValues, "Edm.TimeOfDay", outputCollection, typeof(TimeOfDay), addToDelegate, false);
            outputCollection.Should().HaveCount(3);
            outputCollection[0].Should().Be(TimeOfDay.MinValue);
            outputCollection[1].Should().Be(new TimeOfDay(19, 9, 28, 123));
            outputCollection[2].Should().Be(TimeOfDay.MaxValue);
        }
Example #15
0
        /// <summary>Initializes a new <see cref="ProjectionPathSegment"/> instance.</summary>
        /// <param name="startPath">Path on which this segment is located.</param>
        /// <param name="memberExpression">Member expression for the projection path; possibly null.</param>
        internal ProjectionPathSegment(ProjectionPath startPath, MemberExpression memberExpression)
        {
            Debug.Assert(startPath != null, "startPath != null");
            Debug.Assert(memberExpression != null, "memberExpression != null");

            this.StartPath = startPath;

            Expression source = ResourceBinder.StripTo <Expression>(memberExpression.Expression);

            this.Member         = ClientTypeUtil.GetServerDefinedName(memberExpression.Member);
            this.ProjectionType = memberExpression.Type;
            this.SourceTypeAs   = source.NodeType == ExpressionType.TypeAs ? source.Type : null;
        }
Example #16
0
        /// <summary>Gets a delegate that can be invoked to add an item to a collection of the specified type.</summary>
        /// <param name='listType'>Type of list to use.</param>
        /// <returns>The delegate to invoke.</returns>
        internal static Action <object, object> GetAddToCollectionDelegate(Type listType)
        {
            Debug.Assert(listType != null, "listType != null");

            Type                listElementType;
            MethodInfo          addMethod = ClientTypeUtil.GetAddToCollectionMethod(listType, out listElementType);
            ParameterExpression list      = Expression.Parameter(typeof(object), "list");
            ParameterExpression item      = Expression.Parameter(typeof(object), "element");
            Expression          body      = Expression.Call(Expression.Convert(list, listType), addMethod, Expression.Convert(item, listElementType));
            LambdaExpression    lambda    = Expression.Lambda(body, list, item);

            return((Action <object, object>)lambda.Compile());
        }
Example #17
0
        public void ShouldMaterializeNullableIntCollection()
        {
            var primitiveValues  = new List <int?>(new int?[] { 1, null, 10 });
            var outputCollection = new List <int?>();
            var addToDelegate    = ClientTypeUtil.GetAddToCollectionDelegate(outputCollection.GetType());

            this.CreateCollectionValueMaterializationPolicy().ApplyCollectionDataValues(
                primitiveValues, "Edm.Int32", outputCollection, typeof(int?), addToDelegate, true);
            outputCollection.Should().HaveCount(3);
            outputCollection[0].Should().Be(1);
            outputCollection[1].Should().Be(null);
            outputCollection[2].Should().Be(10);
        }
Example #18
0
 internal static string GetEntityTypeNameForUriAndValidateMaxProtocolVersion(Type type, DataServiceContext context, ref Version uriVersion)
 {
     if (context.MaxProtocolVersionAsVersion < Util.DataServiceVersion3)
     {
         throw new NotSupportedException(Strings.ALinq_TypeAsNotSupportedForMaxDataServiceVersionLessThan3);
     }
     if (!ClientTypeUtil.TypeOrElementTypeIsEntity(type))
     {
         throw new NotSupportedException(Strings.ALinq_TypeAsArgumentNotEntityType(type.FullName));
     }
     WebUtil.RaiseVersion(ref uriVersion, Util.DataServiceVersion3);
     return(context.ResolveNameFromType(type) ?? type.FullName);
 }
Example #19
0
        public void ShouldMaterializeDateCollection()
        {
            var primitiveValues  = new List <Date>(new Date[] { Date.MinValue, new Date(2014, 9, 28), Date.MaxValue });
            var outputCollection = new List <Date>();
            var addToDelegate    = ClientTypeUtil.GetAddToCollectionDelegate(outputCollection.GetType());

            this.CreateCollectionValueMaterializationPolicy().ApplyCollectionDataValues(
                primitiveValues, "Edm.Date", outputCollection, typeof(Date), addToDelegate, false);
            outputCollection.Should().HaveCount(3);
            outputCollection[0].Should().Be(Date.MinValue);
            outputCollection[1].Should().Be(new Date(2014, 9, 28));
            outputCollection[2].Should().Be(Date.MaxValue);
        }
        /// <summary>
        /// Checks whether the specified expression is allowed in a MethodCall. Expressions that
        /// produce collections are not allowed. The only exception is when collection property
        /// belongs to an entity e.g. c.Orders.Select(o => o), where we allow c.Orders.
        /// </summary>
        /// <param name="e">Expression to check.</param>
        /// <param name="model">The client model used.</param>
        /// <returns>true if expression is disallowed, false otherwise.</returns>
        internal static bool IsDisallowedExpressionForMethodCall(Expression e, ClientEdmModel model)
        {
            // If this is a collection hanging off a Entity, then that is fine.
            MemberExpression me = e as MemberExpression;

            if (me != null && ClientTypeUtil.TypeIsEntity(me.Expression.Type, model))
            {
                return(false);
            }

            // All collection producing expressions are disallowed.
            return(IsCollectionProducingExpression(e));
        }
Example #21
0
        /// <summary>
        /// Determine if the specified type is an entity type.
        /// </summary>
        /// <param name="type">An object type specifier.</param>
        /// <param name="model">The client model.</param>
        /// <returns>true if the type is an entity type; otherwise false.</returns>
        internal static bool IsEntityType(Type type, ClientEdmModel model)
        {
            Debug.Assert(type != null, "Argument 'type' cannot be null.");

            metadataCacheLock.EnterReadLock();
            try
            {
                if (knownNonEntityTypes.Contains(type))
                {
                    return(false);
                }
            }
            finally
            {
                metadataCacheLock.ExitReadLock();
            }

            bool isEntityType;

            try
            {
                if (BindingEntityInfo.IsDataServiceCollection(type, model))
                {
                    return(false);
                }

                isEntityType = ClientTypeUtil.TypeOrElementTypeIsEntity(type);
            }
            catch (InvalidOperationException)
            {
                isEntityType = false;
            }

            if (!isEntityType)
            {
                metadataCacheLock.EnterWriteLock();
                try
                {
                    if (!knownNonEntityTypes.Contains(type))
                    {
                        knownNonEntityTypes.Add(type);
                    }
                }
                finally
                {
                    metadataCacheLock.ExitWriteLock();
                }
            }

            return(isEntityType);
        }
Example #22
0
        /// <summary>
        /// Resolves the client type that should be used for materialization.
        /// </summary>
        /// <param name="expectedType">Expected client clr type based on the API called.</param>
        /// <param name="readerTypeName">
        /// The name surfaced by the ODataLib reader.
        /// If we have a server model, this will be a server type name that needs to be resolved.
        /// If not, then this will already be a client type name.</param>
        /// <returns>The resolved annotation for the client type to materialize into.</returns>
        internal ClientTypeAnnotation ResolveTypeForMaterialization(Type expectedType, string readerTypeName)
        {
            // If its a collection, get the collection item name
            string collectionItemTypeName = WebUtil.GetCollectionItemWireTypeName(readerTypeName);

            if (collectionItemTypeName == null)
            {
                // Resolve the primitive type first
                PrimitiveType primitiveType;
                if (PrimitiveType.TryGetPrimitiveType(readerTypeName, out primitiveType))
                {
                    return(this.clientEdmModel.GetClientTypeAnnotation(primitiveType.ClrType));
                }

                ClientTypeAnnotation resultType;
                if (this.edmTypeNameMap.TryGetValue(readerTypeName, out resultType))
                {
                    return(resultType);
                }

                if (this.serviceModel != null)
                {
                    var resolvedType = this.ResolveTypeFromName(readerTypeName, expectedType);
                    return(this.clientEdmModel.GetClientTypeAnnotation(resolvedType));
                }

                // If there was no type name specified in the payload, then the type resolver won't be invoked
                // and hence that edm type name might not be in the resolver cache. Hence look that up in the
                // ClientEdmModel cache. This lookup is more expensive and is unique across the app domain for the
                // given version.
                return(this.clientEdmModel.GetClientTypeAnnotation(readerTypeName));
            }

            Type collectionImplementationType = ClientTypeUtil.GetImplementationType(expectedType, typeof(ICollection <>));
            Type collectionElementType        = collectionImplementationType.GetGenericArguments()[0];

            // In case of collection, the expectedType might be collection of nullable types (for e.g. ICollection<int?>).
            // There is no way to know the nullability from the wireTypeName (For e.g. Collection(Edm.Int32)).
            // Hence in case of collections of primitives, we need to look at the element type of the expected type
            // and use that to create the instance otherwise we will not be able to assign the created ICollection<>
            // instance to the property on the user's entity (ICollection<int> cannot be assigned to ICollection<int?>).
            // There is also no need to invoke the resolver for primitives, so we just use the element type.
            if (!PrimitiveType.IsKnownType(collectionElementType))
            {
                collectionElementType = this.ResolveTypeForMaterialization(collectionElementType, collectionItemTypeName).ElementType;
            }

            Type clrCollectionType = WebUtil.GetBackingTypeForCollectionProperty(expectedType);

            return(this.clientEdmModel.GetClientTypeAnnotation(clrCollectionType));
        }
Example #23
0
 internal override Expression VisitInvocation(InvocationExpression iv)
 {
     if ((ClientTypeUtil.TypeOrElementTypeIsEntity(iv.Expression.Type) || ProjectionAnalyzer.IsCollectionProducingExpression(iv.Expression)) || iv.Arguments.Any <Expression>(delegate(Expression a) {
         if (!ClientTypeUtil.TypeOrElementTypeIsEntity(a.Type))
         {
             return(ProjectionAnalyzer.IsCollectionProducingExpression(a));
         }
         return(true);
     }))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, iv.ToString()));
     }
     return(base.VisitInvocation(iv));
 }
Example #24
0
 internal override Expression VisitConditional(ConditionalExpression c)
 {
     ResourceBinder.PatternRules.MatchNullCheckResult result = ResourceBinder.PatternRules.MatchNullCheck(this.box.ParamExpressionInScope, c);
     if (result.Match)
     {
         this.Visit(result.AssignExpression);
         return(c);
     }
     if (((ClientTypeUtil.TypeOrElementTypeIsEntity(c.Test.Type) || ClientTypeUtil.TypeOrElementTypeIsEntity(c.IfTrue.Type)) || (ClientTypeUtil.TypeOrElementTypeIsEntity(c.IfFalse.Type) || ProjectionAnalyzer.IsCollectionProducingExpression(c.Test))) || (ProjectionAnalyzer.IsCollectionProducingExpression(c.IfTrue) || ProjectionAnalyzer.IsCollectionProducingExpression(c.IfFalse)))
     {
         throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, c.ToString()));
     }
     return(base.VisitConditional(c));
 }
Example #25
0
        /// <summary>
        /// Creates an Edm property.
        /// </summary>
        /// <param name="declaringType">Type declaring this property.</param>
        /// <param name="propertyInfo">PropertyInfo instance for this property.</param>
        /// <returns>Returns a new instance of Edm property.</returns>
        private IEdmProperty CreateEdmProperty(IEdmStructuredType declaringType, PropertyInfo propertyInfo)
        {
            IEdmType propertyEdmType = this.GetOrCreateEdmType(propertyInfo.PropertyType);

            Debug.Assert(
                propertyEdmType.TypeKind == EdmTypeKind.Entity ||
                propertyEdmType.TypeKind == EdmTypeKind.Complex ||
                propertyEdmType.TypeKind == EdmTypeKind.Enum ||
                propertyEdmType.TypeKind == EdmTypeKind.Primitive ||
                propertyEdmType.TypeKind == EdmTypeKind.Collection,
                "Property kind should be Entity, Complex, Enum, Primitive or Collection.");

            IEdmProperty edmProperty        = null;
            bool         isPropertyNullable = ClientTypeUtil.CanAssignNull(propertyInfo.PropertyType);

            if (propertyEdmType.TypeKind == EdmTypeKind.Entity || (propertyEdmType.TypeKind == EdmTypeKind.Collection && ((IEdmCollectionType)propertyEdmType).ElementType.TypeKind() == EdmTypeKind.Entity))
            {
                if (declaringType.TypeKind == EdmTypeKind.Entity || declaringType.TypeKind == EdmTypeKind.Complex)
                {
                    if (declaringType as IEdmEntityType == null && declaringType as IEdmComplexType == null)
                    {
                        throw c.Error.InvalidOperation(c.Strings.ClientTypeCache_NonEntityTypeOrNonComplexTypeCannotContainEntityProperties(propertyInfo.Name, propertyInfo.DeclaringType.ToString()));
                    }

                    // Create a navigation property representing one side of an association.
                    // The partner representing the other side exists only inside this property and is not added to the target entity type,
                    // so it should not cause any name collisions.
                    edmProperty = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                        ClientTypeUtil.GetServerDefinedName(propertyInfo),
                        propertyEdmType.ToEdmTypeReference(isPropertyNullable),
                        /*dependentProperties*/ null,
                        /*principalProperties*/ null,
                        /*containsTarget*/ false,
                        EdmOnDeleteAction.None,
                        "Partner",
                        declaringType.ToEdmTypeReference(true),
                        /*partnerDependentProperties*/ null,
                        /*partnerPrincipalProperties*/ null,
                        /*partnerContainsTarget*/ false,
                        EdmOnDeleteAction.None);
                }
            }
            else
            {
                edmProperty = new EdmStructuralProperty(declaringType, ClientTypeUtil.GetServerDefinedName(propertyInfo), propertyEdmType.ToEdmTypeReference(isPropertyNullable));
            }

            edmProperty.SetClientPropertyAnnotation(new ClientPropertyAnnotation(edmProperty, propertyInfo, this));
            return(edmProperty);
        }
Example #26
0
        public void AddingCollectionToPrimitiveCollectionShouldFail()
        {
            var collectionValues = new List <object>(new object[] { new ODataCollectionValue() });

            var outputCollection = new List <int>();
            var addToDelegate    = ClientTypeUtil.GetAddToCollectionDelegate(outputCollection.GetType());

            Action test =
                () =>
                this.CreateCollectionValueMaterializationPolicy().ApplyCollectionDataValues(
                    collectionValues, "Edm.Int32", outputCollection, typeof(int), addToDelegate, false);

            test.ShouldThrow <InvalidOperationException>(DSClient.Strings.Collection_CollectionTypesInCollectionOfPrimitiveTypesNotAllowed);
        }
Example #27
0
        public void AddingPrimitiveValueToComplexCollectionShouldFail()
        {
            var primitiveValues = new List <object>(new object[] { 1 });

            var outputCollection = new List <Point>();
            var addToDelegate    = ClientTypeUtil.GetAddToCollectionDelegate(outputCollection.GetType());

            Action test =
                () =>
                this.CreateCollectionValueMaterializationPolicy().ApplyCollectionDataValues(
                    primitiveValues, "Point", outputCollection, typeof(Point), addToDelegate, false);

            test.ShouldThrow <InvalidOperationException>(DSClient.Strings.Collection_PrimitiveTypesInCollectionOfComplexTypesNotAllowed);
        }
        [TestMethod] public void NullComplexValueShouldFail()
        {
            var primitiveValues = new List <ODataComplexValue>(new ODataComplexValue[] { null });

            var outputCollection = new List <Point>();
            var addToDelegate    = ClientTypeUtil.GetAddToCollectionDelegate(outputCollection.GetType());

            Action test =
                () =>
                this.CreateCollectionValueMaterializationPolicy().ApplyCollectionDataValues(
                    primitiveValues, "Point", outputCollection, typeof(Point), addToDelegate, false);

            test.ShouldThrow <InvalidOperationException>().WithMessage(DSClient.Strings.Collection_NullCollectionItemsNotSupported);
        }
Example #29
0
        /// <summary>
        /// Reads a value from the message reader.
        /// </summary>
        /// <param name="expectedClientType">The expected client type being materialized into.</param>
        /// <param name="expectedReaderType">The expected type for the underlying reader.</param>
        protected override void ReadWithExpectedType(IEdmTypeReference expectedClientType, IEdmTypeReference expectedReaderType)
        {
            if (!expectedClientType.IsCollection())
            {
                throw new DataServiceClientException(DSClient.Strings.AtomMaterializer_TypeShouldBeCollectionError(expectedClientType.FullName()));
            }

            Type underlyingExpectedType = Nullable.GetUnderlyingType(this.ExpectedType) ?? this.ExpectedType;

            Debug.Assert(WebUtil.IsCLRTypeCollection(underlyingExpectedType, this.MaterializerContext.Model) ||
                         (SingleResult.HasValue && !SingleResult.Value), "expected type must be collection or single result must be false");

            // We are here for two cases:
            // (1) Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
            // (2) Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
            Type collectionItemType        = underlyingExpectedType;
            Type collectionICollectionType = ClientTypeUtil.GetImplementationType(underlyingExpectedType, typeof(ICollection <>));

            if (collectionICollectionType != null)
            {
                // Case 1 : Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
                collectionItemType = collectionICollectionType.GetGenericArguments()[0];
            }
            else
            {
                // Case 2 : Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
                collectionICollectionType = typeof(ICollection <>).MakeGenericType(new Type[] { collectionItemType });
            }

            Type   clrCollectionType  = WebUtil.GetBackingTypeForCollectionProperty(collectionICollectionType);
            object collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionInstance((IEdmCollectionTypeReference)expectedClientType, clrCollectionType);

            // Enumerator over our collection reader was created, then ApplyDataCollections was refactored to
            // take an enumerable instead of a ODataCollectionValue. Enumerator is being used as a bridge
            ODataCollectionReader    collectionReader     = messageReader.CreateODataCollectionReader();
            NonEntityItemsEnumerable collectionEnumerable = new NonEntityItemsEnumerable(collectionReader);

            bool isElementNullable = expectedClientType.AsCollection().ElementType().IsNullable;

            this.CollectionValueMaterializationPolicy.ApplyCollectionDataValues(
                collectionEnumerable,
                null /*wireTypeName*/,
                collectionInstance,
                collectionItemType,
                ClientTypeUtil.GetAddToCollectionDelegate(collectionICollectionType),
                isElementNullable);

            this.currentValue = collectionInstance;
        }
        public void ShouldMaterializeComplexCollection()
        {
            var primitiveValues = new List <ODataComplexValue>(new ODataComplexValue[]
            {
                new ODataComplexValue()
                {
                    Properties = new ODataProperty[] { new ODataProperty()
                                                       {
                                                           Name = "X", Value = 15
                                                       }, new ODataProperty()
                                                       {
                                                           Name = "Y", Value = 18
                                                       } }
                },
                new ODataComplexValue()
                {
                    Properties = new ODataProperty[] { new ODataProperty()
                                                       {
                                                           Name = "X", Value = 22
                                                       }, new ODataProperty()
                                                       {
                                                           Name = "Y", Value = 25
                                                       } }
                },
                new ODataComplexValue()
                {
                    Properties = new ODataProperty[] { new ODataProperty()
                                                       {
                                                           Name = "X", Value = -100
                                                       }, new ODataProperty()
                                                       {
                                                           Name = "Y", Value = -201
                                                       } }
                },
            });

            var outputCollection = new List <Point>();
            var addToDelegate    = ClientTypeUtil.GetAddToCollectionDelegate(outputCollection.GetType());

            this.CreateCollectionValueMaterializationPolicy().ApplyCollectionDataValues(
                primitiveValues, "Point", outputCollection, typeof(Point), addToDelegate, false);
            outputCollection.Should().HaveCount(3);
            outputCollection[0].X.Should().Be(15);
            outputCollection[0].Y.Should().Be(18);
            outputCollection[1].X.Should().Be(22);
            outputCollection[1].Y.Should().Be(25);
            outputCollection[2].X.Should().Be(-100);
            outputCollection[2].Y.Should().Be(-201);
        }