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;
        }
Beispiel #6
0
        /// <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)));
        }
Beispiel #7
0
        /// <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)));
        }
Beispiel #8
0
        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);
                }
            }
        }
Beispiel #9
0
        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);
                }
            }
        }
Beispiel #11
0
 /// <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)
 {
 }
Beispiel #12
0
        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);
                }
            }
        }