protected NavigationSourceConfiguration(ODataModelBuilder modelBuilder, EntityTypeConfiguration entityType, string name) { if (modelBuilder == null) { throw Error.ArgumentNull("modelBuilder"); } if (entityType == null) { throw Error.ArgumentNull("entityType"); } if (String.IsNullOrEmpty(name)) { throw Error.ArgumentNullOrEmpty("name"); } _modelBuilder = modelBuilder; Name = name; EntityType = entityType; ClrType = entityType.ClrType; _url = Name; _editLinkBuilder = null; _readLinkBuilder = null; _navigationPropertyLinkBuilders = new Dictionary<NavigationPropertyConfiguration, NavigationLinkBuilder>(); _navigationPropertyBindings = new Dictionary<NavigationPropertyConfiguration, NavigationPropertyBindingConfiguration>(); }
/// <summary> /// Initializes a new instance of the <see cref="NavigationPropertyConfiguration"/> class. /// </summary> /// <param name="property">The backing CLR property.</param> /// <param name="multiplicity">The <see cref="EdmMultiplicity"/>.</param> /// <param name="declaringType">The declaring entity type.</param> public NavigationPropertyConfiguration(PropertyInfo property, EdmMultiplicity multiplicity, EntityTypeConfiguration declaringType) : base(property, declaringType) { if (property == null) { throw Error.ArgumentNull("property"); } Multiplicity = multiplicity; _relatedType = property.PropertyType; if (multiplicity == EdmMultiplicity.Many) { Type elementType; if (!_relatedType.IsCollection(out elementType)) { throw Error.Argument("property", SRResources.ManyToManyNavigationPropertyMustReturnCollection, property.Name, property.DeclaringType.Name); } _relatedType = elementType; } OnDeleteAction = EdmOnDeleteAction.None; }
public static IEnumerable<EntityTypeConfiguration> DerivedTypes(this ODataModelBuilder modelBuilder, EntityTypeConfiguration entity) { if (modelBuilder == null) { throw Error.ArgumentNull("modelBuilder"); } if (entity == null) { throw Error.ArgumentNull("entity"); } IEnumerable<EntityTypeConfiguration> derivedEntities = modelBuilder.StructuralTypes .OfType<EntityTypeConfiguration>().Where(e => e.BaseType == entity); foreach (EntityTypeConfiguration derivedType in derivedEntities) { yield return derivedType; foreach (EntityTypeConfiguration derivedDerivedType in modelBuilder.DerivedTypes(derivedType)) { yield return derivedDerivedType; } } }
/// <summary> /// Initializes a new instance of the <see cref="SingletonConfiguration"/> class. /// </summary> /// <param name="modelBuilder">The <see cref="ODataModelBuilder"/>.</param> /// <param name="entityType">The entity type <see cref="EntityTypeConfiguration"/> contained in this singleton.</param> /// <param name="name">The name of the singleton.</param> public SingletonConfiguration(ODataModelBuilder modelBuilder, EntityTypeConfiguration entityType, string name) : base(modelBuilder, entityType, name) { }
/// <summary> /// Sets the base type of this entity type. /// </summary> /// <param name="baseType">The base entity type.</param> /// <returns>Returns itself so that multiple calls can be chained.</returns> public virtual EntityTypeConfiguration DerivesFrom(EntityTypeConfiguration baseType) { if ((Keys.Any() || EnumKeys.Any()) && baseType.Keys().Any()) { throw Error.InvalidOperation(SRResources.CannotDefineKeysOnDerivedTypes, FullName, baseType.FullName); } DerivesFromImpl(baseType); return this; }
/// <summary> /// Registers an entity set as a part of the model and returns an object that can be used to configure the entity set. /// This method can be called multiple times for the same type to perform multiple lines of configuration. /// </summary> /// <typeparam name="TEntityType">The entity type of the entity set.</typeparam> /// <param name="name">The name of the entity set.</param> /// <returns>The configuration object for the specified entity set.</returns> public EntitySetConfiguration <TEntityType> EntitySet <TEntityType>(string name) where TEntityType : class { EntityTypeConfiguration entity = AddEntityType(typeof(TEntityType)); return(new EntitySetConfiguration <TEntityType>(this, AddEntitySet(name, entity))); }
/// <summary> /// Registers a singleton as a part of the model and returns an object that can be used to configure the singleton. /// This method can be called multiple times for the same type to perform multiple lines of configuration. /// </summary> /// <typeparam name="TEntityType">The entity type of the singleton.</typeparam> /// <param name="name">The name of the singleton.</param> /// <returns>The configuration object for the specified singleton.</returns> public SingletonConfiguration <TEntityType> Singleton <TEntityType>(string name) where TEntityType : class { EntityTypeConfiguration entity = AddEntityType(typeof(TEntityType)); return(new SingletonConfiguration <TEntityType>(this, AddSingleton(name, entity))); }
private void CreateNavigationProperty(EntityTypeConfiguration config) { Contract.Assert(config != null); EdmEntityType type = (EdmEntityType)(GetEdmType(config.ClrType)); foreach (NavigationPropertyConfiguration navProp in config.NavigationProperties) { EdmNavigationPropertyInfo info = new EdmNavigationPropertyInfo { Name = navProp.Name, TargetMultiplicity = navProp.Multiplicity, Target = GetEdmType(navProp.RelatedClrType) as IEdmEntityType, ContainsTarget = navProp.ContainsTarget, OnDelete = navProp.OnDeleteAction }; // Principal properties if (navProp.PrincipalProperties.Any()) { info.PrincipalProperties = GetDeclaringPropertyInfo(navProp.PrincipalProperties); } // Dependent properties if (navProp.DependentProperties.Any()) { info.DependentProperties = GetDeclaringPropertyInfo(navProp.DependentProperties); } IEdmProperty edmProperty = type.AddUnidirectionalNavigation(info); if (navProp.PropertyInfo != null && edmProperty != null) { _properties[navProp.PropertyInfo] = edmProperty; } if (edmProperty != null && navProp.IsRestricted) { _propertiesRestrictions[edmProperty] = new QueryableRestrictions(navProp); } } }
private void CreateEntityTypeBody(EdmEntityType type, EntityTypeConfiguration config) { Contract.Assert(type != null); Contract.Assert(config != null); CreateStructuralTypeBody(type, config); IEnumerable<IEdmStructuralProperty> keys = config.Keys.Select(p => type.DeclaredProperties.OfType<IEdmStructuralProperty>().First(dp => dp.Name == p.Name)); type.AddKeys(keys); // Add the Enum keys keys = config.EnumKeys.Select(p => type.DeclaredProperties.OfType<IEdmStructuralProperty>().First(dp => dp.Name == p.Name)); type.AddKeys(keys); }
// 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); } } }
/// <summary> /// Initializes a new instance of the <see cref="EntitySetConfiguration"/> class. /// </summary> /// <param name="modelBuilder">The <see cref="ODataModelBuilder"/>.</param> /// <param name="entityType">The entity type <see cref="EntityTypeConfiguration"/> contained in this entity set.</param> /// <param name="name">The name of the entity set.</param> public EntitySetConfiguration(ODataModelBuilder modelBuilder, EntityTypeConfiguration entityType, string name) : base(modelBuilder, entityType, name) { }
private void CreateEdmTypeHeader(IEdmTypeConfiguration config) { IEdmType edmType = GetEdmType(config.ClrType); if (edmType == 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); } if (complex.SupportsInstanceAnnotations) { // add a mapping between the complex type and its instance annotation dictionary. _instanceAnnotableTypes.Add(complexType, complex.InstanceAnnotationsContainer); } edmType = complexType; } 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, entity.HasStream); _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); } if (entity.SupportsInstanceAnnotations) { // add a mapping between the entity type and its instance annotation dictionary. _instanceAnnotableTypes.Add(entityType, entity.InstanceAnnotationsContainer); } edmType = entityType; } 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)); } } IEdmStructuredType structuredType = edmType as IEdmStructuredType; StructuralTypeConfiguration structuralTypeConfiguration = config as StructuralTypeConfiguration; if (structuredType != null && structuralTypeConfiguration != null && !_structuredTypeQuerySettings.ContainsKey(structuredType)) { ModelBoundQuerySettings querySettings = structuralTypeConfiguration.QueryConfiguration.ModelBoundQuerySettings; if (querySettings != null) { _structuredTypeQuerySettings.Add(structuredType, structuralTypeConfiguration.QueryConfiguration.ModelBoundQuerySettings); } } }