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); }
private CollectionPropertyConfiguration GetCollectionPropertyConfiguration(Expression propertyExpression, bool optional = false) { PropertyInfo propertyInfo = PropertySelectorVisitor.GetSelectedProperty(propertyExpression); CollectionPropertyConfiguration property = _configuration.AddCollectionProperty(propertyInfo); if (optional) { property.IsOptional(); } return(property); }
/// <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); }
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; } } }
// 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; }
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; } } }