public EntitySetConfiguration(ODataModelBuilder modelBuilder, EntityTypeConfiguration entityType, string name)
        {
            if (modelBuilder == null)
            {
                throw Error.ArgumentNull("modelBuilder");
            }

            if (entityType == null)
            {
                throw Error.ArgumentNull("entityType");
            }

            if (name == null)
            {
                throw Error.ArgumentNull("name");
            }

            _modelBuilder = modelBuilder;
            Name = name;
            EntityType = entityType;
            ClrType = entityType.ClrType;
            _url = Name;

            _editLinkBuilder = null;
            _readLinkBuilder = null;
            _navigationPropertyLinkBuilders = new Dictionary<NavigationPropertyConfiguration, NavigationLinkBuilder>();
            _entitySetBindings = new Dictionary<NavigationPropertyConfiguration, NavigationPropertyBindingConfiguration>();
        }
		private void AddActionsToProduct(EntityTypeConfiguration<Product> config)
		{
			config.Action("FinalPrice")
				.Returns<decimal>();

			config.Action("LowestPrice")
				.Returns<decimal>();
		}
        // Returns the base types, this type and all the derived types of this type.
        public static IEnumerable<EntityTypeConfiguration> ThisAndBaseAndDerivedTypes(this ODataModelBuilder modelBuilder, EntityTypeConfiguration entity)
        {
            Contract.Assert(modelBuilder != null);
            Contract.Assert(entity != null);

            return entity.BaseTypes()
                    .Concat(new[] { entity })
                    .Concat(modelBuilder.DerivedTypes(entity));
        }
        public void CtorThatTakesEntityTypeConfiguration_Sets_Property_EntityType()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration entityType = new EntityTypeConfiguration(new ODataModelBuilder(), typeof(EntitySetConfigurationTest));

            // Act
            EntitySetConfiguration entityset = new EntitySetConfiguration(builder, entityType, "entityset");

            // Assert
            Assert.Equal(entityType, entityset.EntityType);
        }
		private void AddActionsToOrder(EntityTypeConfiguration<Order> config)
		{
			config.Action("PaymentPending")
				.ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders);

			config.Action("PaymentPaid")
				.ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders)
				.Parameter<string>("PaymentMethodName");

			config.Action("PaymentRefund")
				.ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders)
				.Parameter<bool>("Online");

			config.Action("Cancel")
				.ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders);
		}
		private void AddActionsToProduct(EntityTypeConfiguration<Product> config)
		{
			config.Action("FinalPrice")
				.Returns<decimal>();

			config.Action("LowestPrice")
				.Returns<decimal>();

			config.Action("CreateAttributeCombinations")
				.ReturnsCollectionFromEntitySet<ProductVariantAttributeCombination>(WebApiOdataEntitySet.ProductVariantAttributeCombinations);

			var manageAttributes = config.Action("ManageAttributes")
				.ReturnsCollectionFromEntitySet<ProductVariantAttribute>(WebApiOdataEntitySet.ProductVariantAttributes);

			manageAttributes.Parameter<bool>("Synchronize");
			manageAttributes.CollectionParameter<ManageAttributeType>("Attributes");
		}
        /// <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.ReflectedType.Name);
                }

                _relatedType = elementType;
            }
        }
        // Returns all the derived types of this type.
        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 derivedEntity in derivedEntities)
            {
                yield return derivedEntity;
                foreach (EntityTypeConfiguration derivedDerivedEntity in modelBuilder.DerivedTypes(derivedEntity))
                {
                    yield return derivedDerivedEntity;
                }
            }
        }
        private void CreateEntityTypeBody(EdmEntityType type, EntityTypeConfiguration config)
        {
            CreateStructuralTypeBody(type, config);
            IEdmStructuralProperty[] keys = config.Keys.Select(p => type.DeclaredProperties.OfType<IEdmStructuralProperty>().First(dp => dp.Name == p.Name)).ToArray();
            type.AddKeys(keys);

            foreach (NavigationPropertyConfiguration navProp in config.NavigationProperties)
            {
                EdmNavigationPropertyInfo info = new EdmNavigationPropertyInfo();
                info.Name = navProp.Name;
                info.TargetMultiplicity = navProp.Multiplicity;
                info.Target = _types[navProp.RelatedClrType] as IEdmEntityType;
                //TODO: If target end has a multiplity of 1 this assumes the source end is 0..1.
                //      I think a better default multiplicity is *
                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 CreateNavigationProperty(EntityTypeConfiguration config)
        {
            Contract.Assert(config != null);

            EdmEntityType entityType = (EdmEntityType)(_types[config.ClrType]);

            foreach (NavigationPropertyConfiguration navProp in config.NavigationProperties)
            {
                EdmNavigationPropertyInfo info = new EdmNavigationPropertyInfo();
                info.Name = navProp.Name;
                info.TargetMultiplicity = navProp.Multiplicity;
                info.Target = _types[navProp.RelatedClrType] as IEdmEntityType;
                info.OnDelete = navProp.OnDeleteAction;

                if (navProp.ReferentialConstraint.Any())
                {
                    info.DependentProperties = ReorderDependentProperties(navProp);
                }

                //TODO: If target end has a multiplity of 1 this assumes the source end is 0..1.
                //      I think a better default multiplicity is *
                entityType.AddUnidirectionalNavigation(info);
            }
        }
        public static bool IsAssignableFrom(this EntityTypeConfiguration baseEntity, EntityTypeConfiguration entity)
        {
            while (entity != null)
            {
                if (baseEntity == entity)
                {
                    return true;
                }
                entity = entity.BaseType;
            }

            return false;
        }
 // Returns the base types, this type.
 public static IEnumerable <EntityTypeConfiguration> ThisAndBaseTypes(this EntityTypeConfiguration entity)
 {
     Contract.Assert(entity != null);
     return(entity.BaseTypes().Concat(new[] { entity }));
 }
 private void CreateEntityTypeBody(EdmEntityType type, EntityTypeConfiguration config)
 {
     CreateStructuralTypeBody(type, config);
     IEdmStructuralProperty[] keys = config.Keys.Select(p => type.DeclaredProperties.OfType<IEdmStructuralProperty>().First(dp => dp.Name == p.PropertyInfo.Name)).ToArray();
     type.AddKeys(keys);
 }
 /// <summary>
 /// Sets the base type of this entity type to <c>null</c> meaning that this entity type 
 /// does not derive from anything.
 /// </summary>
 /// <returns>Returns itself so that multiple calls can be chained.</returns>
 public virtual EntityTypeConfiguration DerivesFromNothing()
 {
     _baseType = null;
     _baseTypeConfigured = true;
     return this;
 }
Exemple #15
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 <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;
                        }
                    }

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

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

                // all derived types and the base type are also reachable
                EntityTypeConfiguration currentEntityType = currentType as EntityTypeConfiguration;
                if (currentEntityType != null)
                {
                    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);
                        }
                    }
                }

                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);
                }
            }
        }
Exemple #16
0
        // remove base type properties from the derived types.
        internal void RemoveBaseTypeProperties(EntityTypeConfiguration derivedEntity, EntityTypeConfiguration baseEntity)
        {
            IEnumerable <EntityTypeConfiguration> typesToLift = new[] { derivedEntity }.Concat(this.DerivedTypes(derivedEntity));

            foreach (PropertyConfiguration property in baseEntity.Properties.Concat(baseEntity.DerivedProperties()))
            {
                foreach (EntityTypeConfiguration entity in typesToLift)
                {
                    PropertyConfiguration derivedPropertyToRemove = entity.Properties.Where(p => p.Name == property.Name).SingleOrDefault();
                    if (derivedPropertyToRemove != null)
                    {
                        entity.RemoveProperty(derivedPropertyToRemove.PropertyInfo);
                    }
                }
            }

            foreach (PropertyInfo ignoredProperty in baseEntity.IgnoredProperties())
            {
                foreach (EntityTypeConfiguration entity in typesToLift)
                {
                    PropertyConfiguration derivedPropertyToRemove = entity.Properties.Where(p => p.Name == ignoredProperty.Name).SingleOrDefault();
                    if (derivedPropertyToRemove != null)
                    {
                        entity.RemoveProperty(derivedPropertyToRemove.PropertyInfo);
                    }
                }
            }
        }
        // Returns all the derived types of this type.
        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 derivedEntity in derivedEntities)
            {
                yield return(derivedEntity);

                foreach (EntityTypeConfiguration derivedDerivedEntity in modelBuilder.DerivedTypes(derivedEntity))
                {
                    yield return(derivedDerivedEntity);
                }
            }
        }
        // Returns the base types, this type and all the derived types of this type.
        public static IEnumerable <EntityTypeConfiguration> ThisAndBaseAndDerivedTypes(this ODataModelBuilder modelBuilder, EntityTypeConfiguration entity)
        {
            Contract.Assert(modelBuilder != null);
            Contract.Assert(entity != null);

            return(entity.BaseTypes()
                   .Concat(new[] { entity })
                   .Concat(modelBuilder.DerivedTypes(entity)));
        }
        private void AddActionsToOrder(EntityTypeConfiguration<Order> config)
        {
            config.Action("PaymentPending")
                .ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders);

            config.Action("PaymentPaid")
                .ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders)
                .Parameter<string>("PaymentMethodName");

            config.Action("PaymentRefund")
                .ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders)
                .Parameter<bool>("Online");

            config.Action("Cancel")
                .ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders);

            var addShipment = config.Action("AddShipment")
                .ReturnsFromEntitySet<Order>(WebApiOdataEntitySet.Orders);

            addShipment.Parameter<string>("TrackingNumber");
            addShipment.Parameter<bool?>("SetAsShipped");
        }
        /// <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.ReflectedType.Name);
                }

                _relatedType = elementType;
            }

            OnDeleteAction = EdmOnDeleteAction.None;
        }
 // returns the keys declared or inherited for this entity
 public static IEnumerable <PropertyConfiguration> Keys(this EntityTypeConfiguration entity)
 {
     Contract.Assert(entity != null);
     return(entity.BaseType == null ? entity.Keys : Keys(entity.BaseType));
 }
        /// <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 (baseType == null)
            {
                throw Error.ArgumentNull("baseType");
            }

            _baseType = baseType;
            _baseTypeConfigured = true;

            if (!baseType.ClrType.IsAssignableFrom(ClrType) || baseType.ClrType == ClrType)
            {
                throw Error.Argument("baseType", SRResources.TypeDoesNotInheritFromBaseType, ClrType.FullName, baseType.ClrType.FullName);
            }

            if (Keys.Any())
            {
                throw Error.InvalidOperation(SRResources.CannotDefineKeysOnDerivedTypes, FullName, baseType.FullName);
            }

            foreach (PropertyConfiguration property in Properties)
            {
                ValidatePropertyNotAlreadyDefinedInBaseTypes(property.PropertyInfo);
            }

            foreach (PropertyConfiguration property in this.DerivedProperties())
            {
                ValidatePropertyNotAlreadyDefinedInDerivedTypes(property.PropertyInfo);
            }

            return this;
        }
Exemple #23
0
 private void CreateEntityTypeBody(EdmEntityType type, EntityTypeConfiguration config)
 {
     CreateStructuralTypeBody(type, config);
     IEdmStructuralProperty[] keys = config.Keys.Select(p => type.DeclaredProperties.OfType <IEdmStructuralProperty>().First(dp => dp.Name == p.PropertyInfo.Name)).ToArray();
     type.AddKeys(keys);
 }