private void CreateComplexTypeBody(EdmComplexType type, ComplexTypeConfiguration config) { Contract.Assert(type != null); Contract.Assert(config != null); CreateStructuralTypeBody(type, config); }
/// <summary> /// Sets the base type of this complex type. /// </summary> /// <param name="baseType">The base complex type.</param> /// <returns>Returns itself so that multiple calls can be chained.</returns> public virtual ComplexTypeConfiguration DerivesFrom(ComplexTypeConfiguration baseType) { DerivesFromImpl(baseType); return this; }
public static IEnumerable<ComplexTypeConfiguration> DerivedTypes(this ODataModelBuilder modelBuilder, ComplexTypeConfiguration complex) { if (modelBuilder == null) { throw Error.ArgumentNull("modelBuilder"); } if (complex == null) { throw Error.ArgumentNull("complex"); } IEnumerable<ComplexTypeConfiguration> derivedComplexs = modelBuilder.StructuralTypes.OfType<ComplexTypeConfiguration>().Where(e => e.BaseType == complex); foreach (ComplexTypeConfiguration derivedType in derivedComplexs) { yield return derivedType; foreach (ComplexTypeConfiguration derivedDerivedType in modelBuilder.DerivedTypes(derivedType)) { yield return derivedDerivedType; } } }
private void CreateEdmTypeHeader(IEdmTypeConfiguration config) { if (GetEdmType(config.ClrType) == null) { if (config.Kind == EdmTypeKind.Complex) { ComplexTypeConfiguration complex = (ComplexTypeConfiguration)config; IEdmComplexType baseType = null; if (complex.BaseType != null) { CreateEdmTypeHeader(complex.BaseType); baseType = GetEdmType(complex.BaseType.ClrType) as IEdmComplexType; Contract.Assert(baseType != null); } EdmComplexType complexType = new EdmComplexType(config.Namespace, config.Name, baseType, complex.IsAbstract ?? false, complex.IsOpen); _types.Add(config.ClrType, complexType); if (complex.IsOpen) { // add a mapping between the open complex type and its dynamic property dictionary. _openTypes.Add(complexType, complex.DynamicPropertyDictionary); } } else if (config.Kind == EdmTypeKind.Entity) { EntityTypeConfiguration entity = config as EntityTypeConfiguration; Contract.Assert(entity != null); IEdmEntityType baseType = null; if (entity.BaseType != null) { CreateEdmTypeHeader(entity.BaseType); baseType = GetEdmType(entity.BaseType.ClrType) as IEdmEntityType; Contract.Assert(baseType != null); } EdmEntityType entityType = new EdmEntityType(config.Namespace, config.Name, baseType, entity.IsAbstract ?? false, entity.IsOpen); _types.Add(config.ClrType, entityType); if (entity.IsOpen) { // add a mapping between the open entity type and its dynamic property dictionary. _openTypes.Add(entityType, entity.DynamicPropertyDictionary); } } else { EnumTypeConfiguration enumTypeConfiguration = config as EnumTypeConfiguration; // The config has to be enum. Contract.Assert(enumTypeConfiguration != null); _types.Add(enumTypeConfiguration.ClrType, new EdmEnumType(enumTypeConfiguration.Namespace, enumTypeConfiguration.Name, GetTypeKind(enumTypeConfiguration.UnderlyingType), enumTypeConfiguration.IsFlags)); } } }
// 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 <StructuralTypeConfiguration> reachableTypes = new Queue <StructuralTypeConfiguration>(_explicitlyAddedTypes); HashSet <StructuralTypeConfiguration> visitedTypes = new HashSet <StructuralTypeConfiguration>(); while (reachableTypes.Count != 0) { StructuralTypeConfiguration 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; } } IEdmTypeConfiguration propertyType = GetStructuralTypeOrNull(property.RelatedClrType); Contract.Assert(propertyType != null, "we should already have seen this type"); var structuralTypeConfiguration = propertyType as StructuralTypeConfiguration; if (structuralTypeConfiguration != null && !visitedTypes.Contains(propertyType)) { reachableTypes.Enqueue(structuralTypeConfiguration); } } // all derived types and the base type are also reachable if (currentType.Kind == EdmTypeKind.Entity) { EntityTypeConfiguration currentEntityType = (EntityTypeConfiguration)currentType; if (currentEntityType.BaseType != null && !visitedTypes.Contains(currentEntityType.BaseType)) { reachableTypes.Enqueue(currentEntityType.BaseType); } foreach (EntityTypeConfiguration derivedType in this.DerivedTypes(currentEntityType)) { if (!visitedTypes.Contains(derivedType)) { reachableTypes.Enqueue(derivedType); } } } else if (currentType.Kind == EdmTypeKind.Complex) { ComplexTypeConfiguration currentComplexType = (ComplexTypeConfiguration)currentType; if (currentComplexType.BaseType != null && !visitedTypes.Contains(currentComplexType.BaseType)) { reachableTypes.Enqueue(currentComplexType.BaseType); } foreach (ComplexTypeConfiguration derivedType in this.DerivedTypes(currentComplexType)) { if (!visitedTypes.Contains(derivedType)) { reachableTypes.Enqueue(derivedType); } } } visitedTypes.Add(currentType); } StructuralTypeConfiguration[] allConfiguredTypes = StructuralTypes.ToArray(); foreach (StructuralTypeConfiguration 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); } } }
internal ComplexTypeConfiguration(ComplexTypeConfiguration configuration) : base(configuration) { }
/// <summary> /// Sets the base type of this complex type. /// </summary> /// <param name="baseType">The base complex type.</param> /// <returns>Returns itself so that multiple calls can be chained.</returns> public virtual ComplexTypeConfiguration DerivesFrom(ComplexTypeConfiguration baseType) { DerivesFromImpl(baseType); return(this); }