예제 #1
0
        public void HasCorrectKindPropertyInfoAndName(PropertyInfo property, Type elementType)
        {
            Mock <IStructuralTypeConfiguration> structuralType = new Mock <IStructuralTypeConfiguration>();
            CollectionPropertyConfiguration     configuration  = new CollectionPropertyConfiguration(property, structuralType.Object);

            Assert.Equal(PropertyKind.Collection, configuration.Kind);
            Assert.Equal(elementType, configuration.ElementType);
            Assert.Equal(elementType, configuration.RelatedClrType);
            Assert.Equal(property, configuration.PropertyInfo);
            Assert.Equal(property.Name, configuration.Name);
            Assert.Equal(structuralType.Object, configuration.DeclaringType);
        }
예제 #2
0
        private CollectionPropertyConfiguration GetCollectionPropertyConfiguration(Expression propertyExpression, bool optional = false)
        {
            PropertyInfo propertyInfo = PropertySelectorVisitor.GetSelectedProperty(propertyExpression);
            CollectionPropertyConfiguration property = _configuration.AddCollectionProperty(propertyInfo);

            if (optional)
            {
                property.IsOptional();
            }

            return(property);
        }
예제 #3
0
        /// <summary>
        /// Adds a collection property to this edm type.
        /// </summary>
        /// <param name="propertyInfo">The property being added.</param>
        /// <returns>The <see cref="CollectionPropertyConfiguration"/> so that the property can be configured further.</returns>
        public virtual CollectionPropertyConfiguration AddCollectionProperty(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw Error.ArgumentNull("propertyInfo");
            }

            if (!propertyInfo.DeclaringType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("propertyInfo", SRResources.PropertyDoesNotBelongToType);
            }

            // Remove from the ignored properties
            if (IgnoredProperties.Contains(propertyInfo))
            {
                RemovedProperties.Remove(propertyInfo);
            }

            CollectionPropertyConfiguration propertyConfiguration = null;

            if (ExplicitProperties.ContainsKey(propertyInfo))
            {
                propertyConfiguration = ExplicitProperties[propertyInfo] as CollectionPropertyConfiguration;
                if (propertyConfiguration == null)
                {
                    throw Error.Argument("propertyInfo", SRResources.MustBeCollectionProperty, propertyInfo.Name, propertyInfo.DeclaringType.FullName);
                }
            }
            else
            {
                propertyConfiguration            = new CollectionPropertyConfiguration(propertyInfo, this);
                ExplicitProperties[propertyInfo] = propertyConfiguration;

                // If the ElementType is the same as this type this is recursive complex type nesting
                if (propertyConfiguration.ElementType == ClrType)
                {
                    throw Error.Argument("propertyInfo",
                                         SRResources.RecursiveComplexTypesNotAllowed,
                                         ClrType.Name,
                                         propertyConfiguration.Name);
                }

                // If the ElementType is not primitive treat as a ComplexType and Add to the model.
                IEdmPrimitiveTypeReference edmType = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(propertyConfiguration.ElementType);
                if (edmType == null)
                {
                    ModelBuilder.AddComplexType(propertyConfiguration.ElementType);
                }
            }

            return(propertyConfiguration);
        }
예제 #4
0
        private void CreateStructuralTypeBody(EdmStructuredType type, StructuralTypeConfiguration config)
        {
            foreach (PropertyConfiguration property in config.Properties)
            {
                IEdmProperty edmProperty = null;

                switch (property.Kind)
                {
                case PropertyKind.Primitive:
                    PrimitivePropertyConfiguration primitiveProperty = property as PrimitivePropertyConfiguration;
                    CreatePrimitiveProperty(primitiveProperty, type, config, out edmProperty);
                    break;

                case PropertyKind.Complex:
                    ComplexPropertyConfiguration complexProperty = property as ComplexPropertyConfiguration;
                    IEdmComplexType complexType = _types[complexProperty.RelatedClrType] as IEdmComplexType;

                    edmProperty = type.AddStructuralProperty(
                        complexProperty.PropertyInfo.Name,
                        new EdmComplexTypeReference(complexType, complexProperty.OptionalProperty));
                    break;

                case PropertyKind.Collection:
                    CollectionPropertyConfiguration collectionProperty = property as CollectionPropertyConfiguration;
                    IEdmTypeReference elementTypeReference             = null;
                    if (_types.ContainsKey(collectionProperty.ElementType))
                    {
                        IEdmComplexType elementType = _types[collectionProperty.ElementType] as IEdmComplexType;
                        elementTypeReference = new EdmComplexTypeReference(elementType, false);
                    }
                    else
                    {
                        elementTypeReference = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(collectionProperty.ElementType);
                    }
                    edmProperty = type.AddStructuralProperty(
                        collectionProperty.PropertyInfo.Name,
                        new EdmCollectionTypeReference(
                            new EdmCollectionType(elementTypeReference),
                            collectionProperty.OptionalProperty));
                    break;

                default:
                    break;
                }

                if (edmProperty != null && property.PropertyInfo != null)
                {
                    _properties[property.PropertyInfo] = edmProperty;
                }
            }
        }
예제 #5
0
        // the convention model builder MapTypes() method might have went through deep object graphs and added a bunch of types
        // only to realise after applying the conventions that the user has ignored some of the properties. So, prune the unreachable stuff.
        private void PruneUnreachableTypes()
        {
            Contract.Assert(_explicitlyAddedTypes != null);

            // Do a BFS starting with the types the user has explicitly added to find out the unreachable nodes.
            Queue <IStructuralTypeConfiguration>   reachableTypes = new Queue <IStructuralTypeConfiguration>(_explicitlyAddedTypes);
            HashSet <IStructuralTypeConfiguration> visitedTypes   = new HashSet <IStructuralTypeConfiguration>();

            while (reachableTypes.Count != 0)
            {
                IStructuralTypeConfiguration currentType = reachableTypes.Dequeue();

                // go visit other end of each of this node's edges.
                foreach (PropertyConfiguration property in currentType.Properties.Where(property => property.Kind != PropertyKind.Primitive))
                {
                    if (property.Kind == PropertyKind.Collection)
                    {
                        // if the elementType is primitive we don't need to do anything.
                        CollectionPropertyConfiguration colProperty = property as CollectionPropertyConfiguration;
                        if (EdmLibHelpers.GetEdmPrimitiveTypeOrNull(colProperty.ElementType) != null)
                        {
                            continue;
                        }
                    }

                    IStructuralTypeConfiguration propertyType = GetStructuralTypeOrNull(property.RelatedClrType);
                    Contract.Assert(propertyType != null, "we should already have seen this type");

                    if (!visitedTypes.Contains(propertyType))
                    {
                        reachableTypes.Enqueue(propertyType);
                    }
                }

                visitedTypes.Add(currentType);
            }

            IStructuralTypeConfiguration[] allConfiguredTypes = StructuralTypes.ToArray();
            foreach (IStructuralTypeConfiguration type in allConfiguredTypes)
            {
                if (!visitedTypes.Contains(type))
                {
                    // we don't have to fix up any properties because this type is unreachable and cannot be a property of any reachable type.
                    RemoveStructuralType(type.ClrType);
                }
            }
        }
        public virtual CollectionPropertyConfiguration AddCollectionProperty(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw Error.ArgumentNull("propertyInfo");
            }

            if (!propertyInfo.DeclaringType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("propertyInfo", SRResources.PropertyDoesNotBelongToType);
            }            

            // Remove from the ignored properties
            if (IgnoredProperties.Contains(propertyInfo))
            {
                RemovedProperties.Remove(propertyInfo);
            }

            CollectionPropertyConfiguration propertyConfiguration = null;
            if (ExplicitProperties.ContainsKey(propertyInfo))
            {
                propertyConfiguration = ExplicitProperties[propertyInfo] as CollectionPropertyConfiguration;
                if (propertyConfiguration == null)
                {
                    throw Error.Argument("propertyInfo", SRResources.MustBeCollectionProperty, propertyInfo.Name, propertyInfo.DeclaringType.FullName);
                }
            }
            else
            {
                propertyConfiguration = new CollectionPropertyConfiguration(propertyInfo);
                ExplicitProperties[propertyInfo] = propertyConfiguration;
                
                // If the ElementType is the same as this type this is recursive complex type nesting
                if (propertyConfiguration.ElementType == ClrType)
                {
                    throw Error.Argument("propertyInfo", 
                                         SRResources.RecursiveComplexTypesNotAllowed,
                                         ClrType.Name,
                                         propertyConfiguration.Name);
                }

                // If the ElementType is not primitive treat as a ComplexType and Add to the model.
                IEdmPrimitiveTypeReference edmType = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(propertyConfiguration.ElementType);
                if (edmType == null)
                {
                    ModelBuilder.AddComplexType(propertyConfiguration.ElementType);
                }
            }

            return propertyConfiguration;
        }
예제 #7
0
        private void CreateStructuralTypeBody(EdmStructuredType type, StructuralTypeConfiguration config)
        {
            foreach (PropertyConfiguration property in config.Properties)
            {
                switch (property.Kind)
                {
                case PropertyKind.Primitive:
                    PrimitivePropertyConfiguration primitiveProperty = property as PrimitivePropertyConfiguration;

                    EdmPrimitiveTypeKind typeKind = GetTypeKind(primitiveProperty.PropertyInfo.PropertyType);
                    IEdmTypeReference    primitiveTypeReference = EdmCoreModel.Instance.GetPrimitive(
                        typeKind,
                        primitiveProperty.OptionalProperty);

                    var primitiveProp = new EdmStructuralProperty(
                        type,
                        primitiveProperty.PropertyInfo.Name,
                        primitiveTypeReference);

                    type.AddProperty(primitiveProp);

                    // Set Annotation StoreGeneratedPattern
                    if (config.Kind == EdmTypeKind.Entity &&
                        primitiveProperty.StoreGeneratedPattern != DatabaseGeneratedOption.None)
                    {
                        _directValueAnnotations.Add(
                            new StoreGeneratedPatternAnnotation(primitiveProp, primitiveProperty.StoreGeneratedPattern));
                    }
                    break;

                case PropertyKind.Complex:
                    ComplexPropertyConfiguration complexProperty = property as ComplexPropertyConfiguration;
                    IEdmComplexType complexType = _types[complexProperty.RelatedClrType] as IEdmComplexType;

                    type.AddStructuralProperty(
                        complexProperty.PropertyInfo.Name,
                        new EdmComplexTypeReference(complexType, complexProperty.OptionalProperty));
                    break;

                case PropertyKind.Collection:
                    CollectionPropertyConfiguration collectionProperty = property as CollectionPropertyConfiguration;
                    IEdmTypeReference elementTypeReference             = null;
                    if (_types.ContainsKey(collectionProperty.ElementType))
                    {
                        IEdmComplexType elementType = _types[collectionProperty.ElementType] as IEdmComplexType;
                        elementTypeReference = new EdmComplexTypeReference(elementType, false);
                    }
                    else
                    {
                        elementTypeReference = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(collectionProperty.ElementType);
                    }
                    type.AddStructuralProperty(
                        collectionProperty.PropertyInfo.Name,
                        new EdmCollectionTypeReference(
                            new EdmCollectionType(elementTypeReference),
                            collectionProperty.OptionalProperty));
                    break;

                default:
                    break;
                }
            }
        }