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; }
// 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); } } }
// 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; }
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); }