示例#1
0
 public CsdlAssociationEnd(string role, CsdlTypeReference type, EdmMultiplicity multiplicity, CsdlOnDelete onDelete, CsdlDocumentation documentation, CsdlLocation location)
     : base(role, documentation, location)
 {
     this.type         = type;
     this.multiplicity = multiplicity;
     this.onDelete     = onDelete;
 }
示例#2
0
 public TBuilder WithMultiplicity(EdmMultiplicity sourceMultiplicity, EdmMultiplicity targetMultiplicity)
 {
     this.ThrowIfAlreadyBuilt();
     this.sourceMultiplicity = sourceMultiplicity;
     this.targetMultiplicity = targetMultiplicity;
     return((TBuilder)(INavigationPropertyBuilder)this);
 }
 public CsdlAssociationEnd(string role, CsdlTypeReference type, EdmMultiplicity multiplicity, CsdlOnDelete onDelete, CsdlDocumentation documentation, CsdlLocation location)
     : base(role, documentation, location)
 {
     this.type = type;
     this.multiplicity = multiplicity;
     this.onDelete = onDelete;
 }
            private IEdmTypeReference ComputeType()
            {
                EdmMultiplicity multiplicity = this.partner.From.Multiplicity;

                switch (multiplicity)
                {
                case EdmMultiplicity.ZeroOrOne:
                {
                    return(new EdmEntityTypeReference(this.partner.DeclaringEntityType(), true));
                }

                case EdmMultiplicity.One:
                {
                    return(new EdmEntityTypeReference(this.partner.DeclaringEntityType(), false));
                }

                case EdmMultiplicity.Many:
                {
                    return(new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(this.partner.DeclaringEntityType(), false)), false));
                }
                }
                EdmError[] edmError = new EdmError[1];
                edmError[0] = new EdmError(this.partner.To.Location(), EdmErrorCode.NavigationPropertyTypeInvalidBecauseOfBadAssociation, Strings.EdmModel_Validator_Semantic_BadNavigationPropertyCouldNotDetermineType(this.partner.DeclaringEntityType().Name));
                return(new BadEntityTypeReference(this.partner.DeclaringEntityType().FullName(), false, edmError));
            }
        private void CheckNavigationWithMultiplicityContainmentEnd(IEdmModel model, EdmMultiplicity multiplicity)
        {
            this.CheckEntityTypeNavigationCount(model, "NS.Person", 3);
            this.CheckEntityTypeNavigationCount(model, "NS.Pet", 3);
            var personNavigations = model.FindEntityType("NS.Person").NavigationProperties();
            var petNavigations = model.FindEntityType("NS.Pet").NavigationProperties();

            var personToOnePet = personNavigations.Where(n => n.Name.Equals("ToOnePet")).First();
            this.CheckNavigationContainment(personToOnePet, true, false);
            this.CheckNavigationMultiplicity(personToOnePet, multiplicity, EdmMultiplicity.One);

            var personToZeroOrOnePet = personNavigations.Where(n => n.Name.Equals("ToZeroOrOnePet")).First();
            this.CheckNavigationContainment(personToZeroOrOnePet, true, false);
            this.CheckNavigationMultiplicity(personToZeroOrOnePet, multiplicity, EdmMultiplicity.ZeroOrOne);

            var personToManyPet = personNavigations.Where(n => n.Name.Equals("ToManyPet")).First();
            this.CheckNavigationContainment(personToManyPet, true, false);
            this.CheckNavigationMultiplicity(personToManyPet, multiplicity, EdmMultiplicity.Many);

            var onePetToPerson = petNavigations.Where(n => n.Name.Equals("OnePetToPerson")).First();
            Assert.AreEqual(personToOnePet.Partner, onePetToPerson, "Invalid navigation partner.");

            var zeroOrOnePetToPerson = petNavigations.Where(n => n.Name.Equals("ZeroOrOnePetToPerson")).First();
            this.CheckNavigationsArePartners(personToZeroOrOnePet, zeroOrOnePetToPerson);

            var manyPetToPerson = petNavigations.Where(n => n.Name.Equals("ManyPetToPerson")).First();
            this.CheckNavigationsArePartners(personToManyPet, manyPetToPerson);
        }
        private void CheckNavigationWithMultiplicityContainmentEnd(IEdmModel model, EdmMultiplicity multiplicity)
        {
            this.CheckEntityTypeNavigationCount(model, "NS.Person", 3);
            this.CheckEntityTypeNavigationCount(model, "NS.Pet", 3);
            var personNavigations = model.FindEntityType("NS.Person").NavigationProperties();
            var petNavigations    = model.FindEntityType("NS.Pet").NavigationProperties();

            var personToOnePet = personNavigations.Where(n => n.Name.Equals("ToOnePet")).First();

            this.CheckNavigationContainment(personToOnePet, true, false);
            this.CheckNavigationMultiplicity(personToOnePet, multiplicity, EdmMultiplicity.One);

            var personToZeroOrOnePet = personNavigations.Where(n => n.Name.Equals("ToZeroOrOnePet")).First();

            this.CheckNavigationContainment(personToZeroOrOnePet, true, false);
            this.CheckNavigationMultiplicity(personToZeroOrOnePet, multiplicity, EdmMultiplicity.ZeroOrOne);

            var personToManyPet = personNavigations.Where(n => n.Name.Equals("ToManyPet")).First();

            this.CheckNavigationContainment(personToManyPet, true, false);
            this.CheckNavigationMultiplicity(personToManyPet, multiplicity, EdmMultiplicity.Many);

            var onePetToPerson = petNavigations.Where(n => n.Name.Equals("OnePetToPerson")).First();

            Assert.AreEqual(personToOnePet.Partner, onePetToPerson, "Invalid navigation partner.");

            var zeroOrOnePetToPerson = petNavigations.Where(n => n.Name.Equals("ZeroOrOnePetToPerson")).First();

            this.CheckNavigationsArePartners(personToZeroOrOnePet, zeroOrOnePetToPerson);

            var manyPetToPerson = petNavigations.Where(n => n.Name.Equals("ManyPetToPerson")).First();

            this.CheckNavigationsArePartners(personToManyPet, manyPetToPerson);
        }
示例#7
0
        public void Apply_TypeNameConventions_Works(string propertyName, EdmMultiplicity multiplicity, bool optional)
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            EntityTypeConfiguration principalEntity = builder.AddEntityType(typeof(DiscoveryPrincipalEntity));
            PropertyInfo            propertyInfo    = typeof(DiscoveryPrincipalEntity).GetProperty(propertyName);

            principalEntity.HasKey(propertyInfo);

            EntityTypeConfiguration dependentEntity    = builder.AddEntityType(typeof(DiscoveryDependentEntity));
            PropertyInfo            expectPropertyInfo = typeof(DiscoveryDependentEntity).GetProperty("DiscoveryPrincipalEntity" + propertyName);
            var property = dependentEntity.AddProperty(expectPropertyInfo);

            PropertyInfo navigationPropertyInfo        = typeof(DiscoveryDependentEntity).GetProperty("Principal");
            NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(navigationPropertyInfo, multiplicity);

            // Act
            new ForeignKeyDiscoveryConvention().Apply(navigation, dependentEntity, builder);

            // Assert
            PropertyInfo actualPropertyInfo = Assert.Single(navigation.DependentProperties);

            Assert.Same(expectPropertyInfo, actualPropertyInfo);

            PropertyInfo principalProperty = Assert.Single(navigation.PrincipalProperties);

            Assert.Equal(propertyName, principalProperty.Name);

            Assert.Equal(optional, property.OptionalProperty);
        }
        public void Apply_TypeNameConventions_Works(string propertyName, EdmMultiplicity multiplicity, bool optional)
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            EntityTypeConfiguration principalEntity = builder.AddEntityType(typeof(DiscoveryPrincipalEntity));
            PropertyInfo propertyInfo = typeof(DiscoveryPrincipalEntity).GetProperty(propertyName);
            principalEntity.HasKey(propertyInfo);

            EntityTypeConfiguration dependentEntity = builder.AddEntityType(typeof(DiscoveryDependentEntity));
            PropertyInfo expectPropertyInfo = typeof(DiscoveryDependentEntity).GetProperty("DiscoveryPrincipalEntity" + propertyName);
            var property = dependentEntity.AddProperty(expectPropertyInfo);

            PropertyInfo navigationPropertyInfo = typeof(DiscoveryDependentEntity).GetProperty("Principal");
            NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(navigationPropertyInfo, multiplicity);

            // Act
            new ForeignKeyDiscoveryConvention().Apply(navigation, dependentEntity, builder);

            // Assert
            PropertyInfo actualPropertyInfo = Assert.Single(navigation.DependentProperties);
            Assert.Same(expectPropertyInfo, actualPropertyInfo);

            PropertyInfo principalProperty = Assert.Single(navigation.PrincipalProperties);
            Assert.Equal(propertyName, principalProperty.Name);

            Assert.Equal(optional, property.OptionalProperty);
        }
        private static HttpStatusCode?GetChangedStatusCodeForNavigationProperty(NavigationPropertySegment navigation)
        {
            EdmMultiplicity multiplicity = navigation.NavigationProperty.TargetMultiplicity();

            return(multiplicity == EdmMultiplicity.ZeroOrOne || multiplicity == EdmMultiplicity.One ?
                   HttpStatusCode.NoContent :
                   (HttpStatusCode?)null);
        }
        private NavigationPropertyConfiguration HasNavigationProperty <TTargetEntity, TPartner>(
            Expression <Func <TStructuralType, TTargetEntity> > navigationPropertyExpression,
            EdmMultiplicity multiplicity,
            Expression <Func <TStructuralType, TTargetEntity, bool> > referentialConstraintExpression = null,
            Expression <Func <TTargetEntity, TPartner> > partnerExpression = null,
            Expression <Func <TStructuralType, TTargetEntity, bool> > partnerConstraintExpression = null) where TTargetEntity : class
        {
            var navigation =
                GetOrCreateNavigationProperty(navigationPropertyExpression, multiplicity);

            if (referentialConstraintExpression != null)
            {
                var referentialConstraints =
                    PropertyPairSelectorVisitor.GetSelectedProperty(referentialConstraintExpression);

                foreach (var constraint in referentialConstraints)
                {
                    navigation.HasConstraint(constraint);
                }
            }

            if (partnerExpression != null)
            {
                var partnerMultiplicity = EdmMultiplicity.One;
                if (typeof(IEnumerable).IsAssignableFrom(typeof(TPartner)))
                {
                    partnerMultiplicity = EdmMultiplicity.Many;
                }
                navigation.Partner =
                    _configuration.ModelBuilder
                    .EntityType <TTargetEntity>()
                    .GetOrCreateNavigationProperty(
                        partnerExpression,
                        partnerMultiplicity);
                _configuration
                .ModelBuilder
                .EntityType <TTargetEntity>()
                .RemoveProperty(partnerExpression);
                //                    ._configuration
                //                    .RemoveProperty(navigation.Partner.PropertyInfo);
                if (partnerConstraintExpression != null)
                {
                    var partnerConstraints =
                        PropertyPairSelectorVisitor.GetSelectedProperty(partnerConstraintExpression);

                    foreach (var constraint in partnerConstraints)
                    {
                        navigation.Partner.HasConstraint(constraint);
                    }
                }
            }

            return(navigation);
        }
示例#11
0
        /// <summary>
        /// Constructs a SingleNavigationNode.
        /// </summary>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="sourceSet">The entity set that this of the previous segment.</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input navigationProperty or source is null.</exception>
        /// <exception cref="ArgumentException">Throws if the input navigationProperty targets more than one entity.</exception>
        public SingleNavigationNode(IEdmNavigationProperty navigationProperty, IEdmEntitySet sourceSet)
        {
            ExceptionUtils.CheckArgumentNotNull(navigationProperty, "navigationProperty");

            EdmMultiplicity multiplicity = navigationProperty.TargetMultiplicityTemporary();

            if (multiplicity != EdmMultiplicity.One && multiplicity != EdmMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_CollectionNavigationNode_MustHaveSingleMultiplicity);
            }

            this.navigationProperty  = navigationProperty;
            this.entityTypeReference = (IEdmEntityTypeReference)this.NavigationProperty.Type;
            this.entitySet           = sourceSet != null?sourceSet.FindNavigationTarget(navigationProperty) : null;
        }
示例#12
0
        /// <summary>
        /// Constructs a SingleNavigationNode.
        /// </summary>
        /// <param name="navigationSource">The navigation source that this of the previous segment.</param>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="bindingPath">The binding path of navigation property</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input navigationProperty.</exception>
        /// <exception cref="ArgumentException">Throws if the input navigationProperty targets more than one entity.</exception>
        internal SingleNavigationNode(IEdmNavigationSource navigationSource, IEdmNavigationProperty navigationProperty, IEdmPathExpression bindingPath)
        {
            ExceptionUtils.CheckArgumentNotNull(navigationProperty, "navigationProperty");

            EdmMultiplicity multiplicity = navigationProperty.TargetMultiplicity();

            if (multiplicity != EdmMultiplicity.One && multiplicity != EdmMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_CollectionNavigationNode_MustHaveSingleMultiplicity);
            }

            this.navigationProperty  = navigationProperty;
            this.entityTypeReference = (IEdmEntityTypeReference)this.NavigationProperty.Type;
            this.bindingPath         = bindingPath;
            this.navigationSource    = navigationSource != null?navigationSource.FindNavigationTarget(navigationProperty, bindingPath) : null;
        }
示例#13
0
        private static string MultiplicityAsXml(EdmMultiplicity endKind)
        {
            switch (endKind)
            {
            case EdmMultiplicity.Many:
                return(CsdlConstants.Value_EndMany);

            case EdmMultiplicity.One:
                return(CsdlConstants.Value_EndRequired);

            case EdmMultiplicity.ZeroOrOne:
                return(CsdlConstants.Value_EndOptional);

            default:
                throw new InvalidOperationException(Strings.UnknownEnumVal_Multiplicity(endKind.ToString()));
            }
        }
示例#14
0
        /// <summary>
        /// Constructs a SingleNavigationNode.
        /// </summary>
        /// <param name="navigationSource">The navigation source that this of the previous segment.</param>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="segments">The path segments parsed in path and query option.</param>
        private SingleNavigationNode(IEdmNavigationSource navigationSource,
                                     IEdmNavigationProperty navigationProperty, List <ODataPathSegment> segments)
        {
            ExceptionUtils.CheckArgumentNotNull(navigationProperty, "navigationProperty");

            EdmMultiplicity multiplicity = navigationProperty.TargetMultiplicity();

            if (multiplicity != EdmMultiplicity.One && multiplicity != EdmMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_CollectionNavigationNode_MustHaveSingleMultiplicity);
            }

            this.navigationProperty  = navigationProperty;
            this.entityTypeReference = (IEdmEntityTypeReference)this.NavigationProperty.Type;
            this.parsedSegments      = segments;
            this.navigationSource    = navigationSource != null?navigationSource.FindNavigationTarget(navigationProperty, BindingPathHelper.MatchBindingPath, this.parsedSegments, out this.bindingPath) : null;
        }
 /// <summary>
 /// Creates a new Silent partner for a navigation property
 /// </summary>
 /// <param name="partnerProperty">The navigation property this is a silent partner of.</param>
 /// <param name="propertyDeleteAction">The on delete action for this side of the association</param>
 /// <param name="multiplicity">The multiplicity of this side of the association.</param>
 /// <param name="name">The name of this navigation property.</param>
 public MetadataProviderEdmSilentNavigationProperty(IEdmNavigationProperty partnerProperty, EdmOnDeleteAction propertyDeleteAction, EdmMultiplicity multiplicity, string name)
 {
     this.partner = partnerProperty;
     this.deleteAction = propertyDeleteAction;
     this.name = name;
     switch (multiplicity)
     {
         case EdmMultiplicity.One:
             this.type = new EdmEntityTypeReference(this.partner.DeclaringEntityType(), false);
             break;
         case EdmMultiplicity.ZeroOrOne:
             this.type = new EdmEntityTypeReference(this.partner.DeclaringEntityType(), true);
             break;
         case EdmMultiplicity.Many:
             this.type = new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(this.partner.DeclaringEntityType(), false)));
             break;
     }
 }
 public override QueryNode Visit(ResourceRangeVariableReferenceNode node)
 {
     if (_rangeVariable.NavigationSource != node.RangeVariable.NavigationSource)
     {
         foreach (IEdmNavigationPropertyBinding propertyBinding in _rangeVariable.NavigationSource.NavigationPropertyBindings)
         {
             if (propertyBinding.Target == node.RangeVariable.NavigationSource)
             {
                 EdmMultiplicity multiplicity = propertyBinding.NavigationProperty.TargetMultiplicity();
                 if (multiplicity == EdmMultiplicity.One || multiplicity == EdmMultiplicity.ZeroOrOne)
                 {
                     var rangeVariableNode = new ResourceRangeVariableReferenceNode("", _rangeVariable);
                     return(new SingleNavigationNode(rangeVariableNode, propertyBinding.NavigationProperty, propertyBinding.Path));
                 }
             }
         }
     }
     return(node);
 }
        public void AddNavigationProperty_ThrowsIfTypeIsDateTime(Type propertyType, EdmMultiplicity multiplicity)
        {
            // Arrange
            MockType type = new MockType("Customer", @namespace: "Contoso");
            MockPropertyInfo property = new MockPropertyInfo(propertyType, "Birthday");
            property.SetupGet(p => p.ReflectedType).Returns(type);
            property.SetupGet(p => p.DeclaringType).Returns(type);

            Mock<EntityTypeConfiguration> mock = new Mock<EntityTypeConfiguration> { CallBase = true };
            EntityTypeConfiguration configuration = mock.Object;
            mock.SetupGet(c => c.ClrType).Returns(type);

            // Act & Assert
            Assert.ThrowsArgument(
                () => configuration.AddNavigationProperty(property, multiplicity),
                "navigationProperty",
                string.Format(
                    "The type '{0}' of property 'Birthday' in the 'Contoso.Customer' type is not a supported type.",
                    propertyType.FullName));
        }
示例#18
0
        private FKeyInfo(EntityTypeInfo dependentInfo, PropertyInfo dependentNavigationProperty, PropertyInfo[] dependentStructuralProperties,
                         EntityTypeInfo principalInfo, PropertyInfo principalNavigationProperty)
        {
            _dependentInfo = dependentInfo;
            _dependentNavigationProperty = dependentNavigationProperty;
            _principalInfo = principalInfo;

            _dependentStructuralProperties = dependentStructuralProperties;
            _dependentMultiplicity         = GetEdmMultiplicity(dependentNavigationProperty?.PropertyType, dependentStructuralProperties);

            if (principalNavigationProperty == null)
            {
                _principalMultiplicity = EdmMultiplicity.Unknown;
            }
            else
            {
                _principalNavigationProperty = principalNavigationProperty;
                _principalMultiplicity       = GetEdmMultiplicity(principalNavigationProperty.PropertyType, dependentStructuralProperties);
            }
        }
        /// <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;
            }
        }
        public NavigationPropertyConfiguration(PropertyInfo property, EdmMultiplicity multiplicity)
            : base(property)
        {
            if (property == null)
            {
                throw Error.ArgumentNull("property");
            }

            Multiplicity = multiplicity;

            _relatedType = property.PropertyType;
            if (multiplicity == EdmMultiplicity.Many)
            {
                //TODO: support use of a non-generic type i.e. public class OrdersCollection: List<Order>
                if (!_relatedType.IsGenericType || _relatedType.GetGenericArguments().Length > 1)
                {
                    throw Error.Argument("property", SRResources.ManyToManyNavigationPropertyMustReturnCollection);
                }

                _relatedType = _relatedType.GetGenericArguments()[0];
            }
        }
        public NavigationPropertyConfiguration(PropertyInfo property, EdmMultiplicity multiplicity, IEntityTypeConfiguration 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.InvalidOperation(SRResources.ManyToManyNavigationPropertyMustReturnCollection, property.Name, property.ReflectedType.Name);
                }

                _relatedType = elementType;
            }
        }
        public NavigationPropertyConfiguration(PropertyInfo property, EdmMultiplicity multiplicity)
            : base(property)
        {
            if (property == null)
            {
                throw Error.ArgumentNull("property");
            }

            Multiplicity = multiplicity;

            _relatedType = property.PropertyType;
            if (multiplicity == EdmMultiplicity.Many)
            {
                //TODO: support use of a non-generic type i.e. public class OrdersCollection: List<Order>
                if (!_relatedType.IsGenericType || _relatedType.GetGenericArguments().Length > 1)
                {
                    throw Error.Argument("property", SRResources.ManyToManyNavigationPropertyMustReturnCollection);
                }

                _relatedType = _relatedType.GetGenericArguments()[0];
            }
        }
        public NavigationPropertyConfiguration AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)
        {
            if (navigationProperty == null)
            {
                throw Error.ArgumentNull("navigationProperty");
            }

            if (navigationProperty.DeclaringType != ClrType)
            {
                throw Error.Argument("navigationProperty", SRResources.PropertyDoesNotBelongToType);
            }

            PropertyConfiguration propertyConfig;
            NavigationPropertyConfiguration navigationPropertyConfig;

            if (ExplicitProperties.ContainsKey(navigationProperty))
            {
                propertyConfig = ExplicitProperties[navigationProperty];
                if (propertyConfig.Kind != PropertyKind.Navigation)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustBeNavigationProperty, navigationProperty.Name);
                }

                navigationPropertyConfig = propertyConfig as NavigationPropertyConfiguration;
                if (navigationPropertyConfig.Multiplicity != multiplicity)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustHaveMatchingMultiplicity, navigationProperty.Name, multiplicity);
                }
            }
            else
            {
                navigationPropertyConfig = new NavigationPropertyConfiguration(navigationProperty, multiplicity);
                ExplicitProperties[navigationProperty] = navigationPropertyConfig;
                // make sure the related type is configured
                ModelBuilder.AddEntity(navigationPropertyConfig.RelatedClrType);
            }
            return navigationPropertyConfig;
        }
        private static string MultiplicityAsXml(EdmMultiplicity endKind)
        {
            EdmMultiplicity edmMultiplicity = endKind;

            switch (edmMultiplicity)
            {
            case EdmMultiplicity.ZeroOrOne:
            {
                return("0..1");
            }

            case EdmMultiplicity.One:
            {
                return("1");
            }

            case EdmMultiplicity.Many:
            {
                return("*");
            }
            }
            throw new InvalidOperationException(Strings.UnknownEnumVal_Multiplicity(endKind.ToString()));
        }
示例#25
0
        private static IEdmTypeReference CreateNavigationPropertyType(IEdmEntityType entityType, EdmMultiplicity multiplicity, string multiplicityParameterName)
        {
            EdmMultiplicity edmMultiplicity = multiplicity;

            switch (edmMultiplicity)
            {
            case EdmMultiplicity.ZeroOrOne:
            {
                return(new EdmEntityTypeReference(entityType, true));
            }

            case EdmMultiplicity.One:
            {
                return(new EdmEntityTypeReference(entityType, false));
            }

            case EdmMultiplicity.Many:
            {
                return(EdmCoreModel.GetCollection(new EdmEntityTypeReference(entityType, false)));
            }
            }
            throw new ArgumentOutOfRangeException(multiplicityParameterName, Strings.UnknownEnumVal_Multiplicity(multiplicity));
        }
        /// <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 structural type.</param>
        public NavigationPropertyConfiguration(PropertyInfo property, EdmMultiplicity multiplicity, StructuralTypeConfiguration declaringType)
            : base(property, declaringType)
        {
            if (property == null)
            {
                throw Error.ArgumentNull("property");
            }

            Multiplicity = multiplicity;

            _relatedType = property.PropertyType;
            if (multiplicity == EdmMultiplicity.Many)
            {
                Type elementType;
                if (!TypeHelper.IsCollection(_relatedType, out elementType))
                {
                    throw Error.Argument("property", SRResources.ManyToManyNavigationPropertyMustReturnCollection, property.Name, TypeHelper.GetReflectedType(property).Name);
                }

                _relatedType = elementType;
            }

            OnDeleteAction = EdmOnDeleteAction.None;
        }
        public void AddNavigationProperty_ThrowsIfTypeIsDateTime(Type propertyType, EdmMultiplicity multiplicity)
        {
            // Arrange
            MockType         type     = new MockType("Customer", @namespace: "Contoso");
            MockPropertyInfo property = new MockPropertyInfo(propertyType, "Birthday");

            property.SetupGet(p => p.ReflectedType).Returns(type);
            property.SetupGet(p => p.DeclaringType).Returns(type);

            Mock <EntityTypeConfiguration> mock = new Mock <EntityTypeConfiguration> {
                CallBase = true
            };
            EntityTypeConfiguration configuration = mock.Object;

            mock.SetupGet(c => c.ClrType).Returns(type);

            // Act & Assert
            Assert.ThrowsArgument(
                () => configuration.AddNavigationProperty(property, multiplicity),
                "navigationProperty",
                string.Format(
                    "The type '{0}' of property 'Birthday' in the 'Contoso.Customer' type is not a supported type.",
                    propertyType.FullName));
        }
        private NavigationPropertyConfiguration AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity, bool containsTarget)
        {
            if (navigationProperty == null)
            {
                throw Error.ArgumentNull("navigationProperty");
            }

            if (!navigationProperty.ReflectedType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("navigationProperty", SRResources.PropertyDoesNotBelongToType, navigationProperty.Name, ClrType.FullName);
            }

            if (navigationProperty.PropertyType == typeof(IEnumerable<DateTime>) ||
                navigationProperty.PropertyType == typeof(IEnumerable<DateTime?>) ||
                navigationProperty.PropertyType == typeof(DateTime) ||
                navigationProperty.PropertyType == typeof(DateTime?))
            {
                throw Error.Argument("navigationProperty", SRResources.DateTimeTypePropertyNotSupported,
                    navigationProperty.PropertyType.FullName, navigationProperty.Name,
                    navigationProperty.DeclaringType.FullName,
                    typeof(DateTimeOffset).FullName, typeof(ODataModelBuilder).FullName);
            }

            ValidatePropertyNotAlreadyDefinedInBaseTypes(navigationProperty);
            ValidatePropertyNotAlreadyDefinedInDerivedTypes(navigationProperty);

            PropertyConfiguration propertyConfig;
            NavigationPropertyConfiguration navigationPropertyConfig;

            if (ExplicitProperties.ContainsKey(navigationProperty))
            {
                propertyConfig = ExplicitProperties[navigationProperty];
                if (propertyConfig.Kind != PropertyKind.Navigation)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustBeNavigationProperty, navigationProperty.Name, ClrType.FullName);
                }

                navigationPropertyConfig = propertyConfig as NavigationPropertyConfiguration;
                if (navigationPropertyConfig.Multiplicity != multiplicity)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustHaveMatchingMultiplicity, navigationProperty.Name, multiplicity);
                }
            }
            else
            {
                navigationPropertyConfig = new NavigationPropertyConfiguration(
                    navigationProperty,
                    multiplicity,
                    this);
                if (containsTarget)
                {
                    navigationPropertyConfig = navigationPropertyConfig.Contained();
                }

                ExplicitProperties[navigationProperty] = navigationPropertyConfig;
                // make sure the related type is configured
                ModelBuilder.AddEntityType(navigationPropertyConfig.RelatedClrType);
            }
            return navigationPropertyConfig;
        }
        /// <summary>
        /// Adds a new EDM navigation property to this entity type.
        /// </summary>
        /// <param name="navigationProperty">The backing CLR property.</param>
        /// <param name="multiplicity">The <see cref="EdmMultiplicity"/> of the navigation property.</param>
        /// <returns>Returns the <see cref="NavigationPropertyConfiguration"/> of the added property.</returns>
        public NavigationPropertyConfiguration AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)
        {
            if (navigationProperty == null)
            {
                throw Error.ArgumentNull("navigationProperty");
            }

            if (!navigationProperty.ReflectedType.IsAssignableFrom(ClrType))
            {
                throw Error.InvalidOperation(SRResources.PropertyDoesNotBelongToType, navigationProperty.Name, ClrType.FullName);
            }

            ValidatePropertyNotAlreadyDefinedInBaseTypes(navigationProperty);
            ValidatePropertyNotAlreadyDefinedInDerivedTypes(navigationProperty);

            PropertyConfiguration           propertyConfig;
            NavigationPropertyConfiguration navigationPropertyConfig;

            if (ExplicitProperties.ContainsKey(navigationProperty))
            {
                propertyConfig = ExplicitProperties[navigationProperty];
                if (propertyConfig.Kind != PropertyKind.Navigation)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustBeNavigationProperty, navigationProperty.Name, ClrType.FullName);
                }

                navigationPropertyConfig = propertyConfig as NavigationPropertyConfiguration;
                if (navigationPropertyConfig.Multiplicity != multiplicity)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustHaveMatchingMultiplicity, navigationProperty.Name, multiplicity);
                }
            }
            else
            {
                navigationPropertyConfig = new NavigationPropertyConfiguration(navigationProperty, multiplicity);
                ExplicitProperties[navigationProperty] = navigationPropertyConfig;
                // make sure the related type is configured
                ModelBuilder.AddEntity(navigationPropertyConfig.RelatedClrType);
            }
            return(navigationPropertyConfig);
        }
示例#30
0
        public MetadataProviderEdmSilentNavigationProperty(IEdmNavigationProperty partnerProperty, EdmOnDeleteAction propertyDeleteAction, EdmMultiplicity multiplicity, string name)
        {
            this.partner      = partnerProperty;
            this.deleteAction = propertyDeleteAction;
            this.name         = name;
            switch (multiplicity)
            {
            case EdmMultiplicity.ZeroOrOne:
                this.type = new EdmEntityTypeReference(this.partner.DeclaringEntityType(), true);
                return;

            case EdmMultiplicity.One:
                this.type = new EdmEntityTypeReference(this.partner.DeclaringEntityType(), false);
                return;

            case EdmMultiplicity.Many:
                this.type = new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(this.partner.DeclaringEntityType(), false)), false);
                return;
            }
        }
示例#31
0
        public static IEdmNavigationProperty AssertHasNavigationProperty(this IEdmStructuredType edmType, IEdmModel model, string propertyName, Type mappedPropertyClrType, bool isNullable, EdmMultiplicity multiplicity)
        {
            IEdmNavigationProperty navigationProperty = edmType.AssertHasProperty <IEdmNavigationProperty>(model, propertyName, propertyType: null, isNullable: isNullable);

            // Bug 468693: in EdmLib. remove when fixed.
            if (multiplicity != EdmMultiplicity.Many)
            {
                Assert.Equal(multiplicity, navigationProperty.Multiplicity());
            }

            Assert.True(navigationProperty.ToEntityType().IsEquivalentTo(model.GetEdmType(mappedPropertyClrType)));
            return(navigationProperty);
        }
示例#32
0
 /// <summary>
 /// Adds a contained EDM navigation property to this entity type.
 /// </summary>
 /// <param name="navigationProperty">The backing CLR property.</param>
 /// <param name="multiplicity">The <see cref="EdmMultiplicity"/> of the navigation property.</param>
 /// <returns>Returns the <see cref="NavigationPropertyConfiguration"/> of the added property.</returns>
 public virtual NavigationPropertyConfiguration AddContainedNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)
 {
     return(AddNavigationProperty(navigationProperty, multiplicity, containsTarget: true));
 }
示例#33
0
        public static IEdmNavigationProperty AssertHasNavigationProperty(this IEdmStructuredType edmType, IEdmModel model, string propertyName, Type mappedPropertyClrType, bool isNullable, EdmMultiplicity multiplicity)
        {
            IEdmNavigationProperty navigationProperty = edmType.AssertHasProperty <IEdmNavigationProperty>(model, propertyName, propertyType: null, isNullable: isNullable);

            Assert.Equal(multiplicity, navigationProperty.TargetMultiplicity());

            Assert.True(navigationProperty.ToEntityType().IsEquivalentTo(model.GetEdmType(mappedPropertyClrType)));
            return(navigationProperty);
        }
 private void CheckNavigationMultiplicity(IEdmNavigationProperty navigation, EdmMultiplicity navigationMultiplicity, EdmMultiplicity navigationPartnerMultiplicity)
 {
     Assert.AreEqual(navigationMultiplicity, navigation.Partner.TargetMultiplicity(), "Invalid navigation property multiplicity.");
     Assert.AreEqual(navigationPartnerMultiplicity, navigation.TargetMultiplicity(), "Invalid navigation property partner multiplicity.");
 }
        private void CheckNavigationWithMultiplicityRecursiveContainmentEnd(IEdmModel model, EdmMultiplicity multiplicity)
        {
            this.CheckEntityTypeNavigationCount(model, "NS.Person", 6);
            var personNavigations = model.FindEntityType("NS.Person").NavigationProperties();

            var manyFriendToPerson = personNavigations.Where(n => n.Name.Equals("ManyFriendToPerson")).First();

            this.CheckNavigationContainment(manyFriendToPerson, false, true);
            this.CheckNavigationMultiplicity(manyFriendToPerson, EdmMultiplicity.Many, multiplicity);

            var zeroOrOneFriendToPerson = personNavigations.Where(n => n.Name.Equals("ZeroOrOneFriendToPerson")).First();

            this.CheckNavigationContainment(zeroOrOneFriendToPerson, false, true);
            this.CheckNavigationMultiplicity(zeroOrOneFriendToPerson, EdmMultiplicity.ZeroOrOne, multiplicity);

            var oneFriendToPerson = personNavigations.Where(n => n.Name.Equals("OneFriendToPerson")).First();

            this.CheckNavigationContainment(oneFriendToPerson, false, true);
            this.CheckNavigationMultiplicity(oneFriendToPerson, EdmMultiplicity.One, multiplicity);

            var toManyFriend = personNavigations.Where(n => n.Name.Equals("ToManyFriend")).First();

            this.CheckNavigationsArePartners(manyFriendToPerson, toManyFriend);

            var toZeroOrOneFriend = personNavigations.Where(n => n.Name.Equals("ToZeroOrOneFriend")).First();

            this.CheckNavigationsArePartners(zeroOrOneFriendToPerson, toZeroOrOneFriend);

            var toOneFriend = personNavigations.Where(n => n.Name.Equals("ToOneFriend")).First();

            this.CheckNavigationsArePartners(oneFriendToPerson, toOneFriend);
        }
示例#36
0
        public static void UpgradeBidirectionalNavigationProperties(Microsoft.OData.Edm.IEdmModel model, string setName, string partnerSetName, string elementTypeName, string partnerElementTypeName, string navigationName, string partnerName, EdmMultiplicity multipl, EdmMultiplicity partnerMultipl)
        {
            var fromSet    = (EdmEntitySet)model.EntityContainer.FindEntitySet(setName);
            var partnerSet = (EdmEntitySet)model.EntityContainer.FindEntitySet(partnerSetName);

            var fromType    = (EdmEntityType)model.FindDeclaredType(elementTypeName);
            var partnerType = (EdmEntityType)model.FindDeclaredType(partnerElementTypeName);

            if (fromType == null)
            {
                throw new Exception("fromType is null");
            }

            if (partnerType == null)
            {
                throw new Exception("partnerType is null");
            }

            var partsProperty = new EdmNavigationPropertyInfo();

            partsProperty.Name = navigationName;
            partsProperty.TargetMultiplicity = multipl;
            partsProperty.Target             = partnerType;
            partsProperty.ContainsTarget     = false;
            partsProperty.OnDelete           = EdmOnDeleteAction.None;

            var partnerProperty = new EdmNavigationPropertyInfo();

            partnerProperty.Name = partnerName;
            partnerProperty.TargetMultiplicity = partnerMultipl;
            partnerProperty.Target             = fromType;
            partnerProperty.ContainsTarget     = false;
            partnerProperty.OnDelete           = EdmOnDeleteAction.None;

            fromSet.AddNavigationTarget(fromType.AddBidirectionalNavigation(partsProperty, partnerProperty), partnerSet);
        }
示例#37
0
        internal static void FixUpNavigationPropertyWithAssociationSetData(IEdmNavigationProperty navigationProperty, IEdmNavigationProperty partner, bool isPrinciple, List <IEdmStructuralProperty> dependentProperties, EdmOnDeleteAction deleteAction, EdmMultiplicity opposingMultiplicity)
        {
            MetadataProviderEdmNavigationProperty property = navigationProperty as MetadataProviderEdmNavigationProperty;

            if (property != null)
            {
                property.FixUpNavigationProperty(partner, isPrinciple, deleteAction);
                if (opposingMultiplicity == EdmMultiplicity.One)
                {
                    property.Type = property.Type.Definition.ToTypeReference(false);
                }
                if ((dependentProperties != null) && !isPrinciple)
                {
                    property.SetDependentProperties(dependentProperties);
                }
            }
            else if ((dependentProperties != null) && !isPrinciple)
            {
                ((MetadataProviderEdmSilentNavigationProperty)navigationProperty).SetDependentProperties(dependentProperties);
            }
        }
示例#38
0
        private static IEdmTypeReference CreateNavigationPropertyType(IEdmEntityType entityType, EdmMultiplicity multiplicity, string multiplicityParameterName)
        {
            switch (multiplicity)
            {
                case EdmMultiplicity.ZeroOrOne:
                    return new EdmEntityTypeReference(entityType, true);

                case EdmMultiplicity.One:
                    return new EdmEntityTypeReference(entityType, false);

                case EdmMultiplicity.Many:
                    return EdmCoreModel.GetCollection(new EdmEntityTypeReference(entityType, false));

                default:
                    throw new ArgumentOutOfRangeException(multiplicityParameterName, Strings.UnknownEnumVal_Multiplicity(multiplicity));
            }
        }
        /// <summary>
        /// Adds a new EDM navigation property to this entity type.
        /// </summary>
        /// <param name="navigationProperty">The backing CLR property.</param>
        /// <param name="multiplicity">The <see cref="EdmMultiplicity"/> of the navigation property.</param>
        /// <returns>Returns the <see cref="NavigationPropertyConfiguration"/> of the added property.</returns>
        public virtual NavigationPropertyConfiguration AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)
        {
            if (navigationProperty == null)
            {
                throw Error.ArgumentNull("navigationProperty");
            }

            if (!navigationProperty.ReflectedType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("navigationProperty", SRResources.PropertyDoesNotBelongToType, navigationProperty.Name, ClrType.FullName);
            }

            ValidatePropertyNotAlreadyDefinedInBaseTypes(navigationProperty);
            ValidatePropertyNotAlreadyDefinedInDerivedTypes(navigationProperty);

            PropertyConfiguration propertyConfig;
            NavigationPropertyConfiguration navigationPropertyConfig;

            if (ExplicitProperties.ContainsKey(navigationProperty))
            {
                propertyConfig = ExplicitProperties[navigationProperty];
                if (propertyConfig.Kind != PropertyKind.Navigation)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustBeNavigationProperty, navigationProperty.Name, ClrType.FullName);
                }

                navigationPropertyConfig = propertyConfig as NavigationPropertyConfiguration;
                if (navigationPropertyConfig.Multiplicity != multiplicity)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustHaveMatchingMultiplicity, navigationProperty.Name, multiplicity);
                }
            }
            else
            {
                navigationPropertyConfig = new NavigationPropertyConfiguration(navigationProperty, multiplicity, this);
                ExplicitProperties[navigationProperty] = navigationPropertyConfig;
                // make sure the related type is configured
                ModelBuilder.AddEntity(navigationPropertyConfig.RelatedClrType);
            }
            return navigationPropertyConfig;
        }
        public NavigationPropertyConfiguration AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)
        {
            if (navigationProperty == null)
            {
                throw Error.ArgumentNull("navigationProperty");
            }

            if (navigationProperty.DeclaringType != ClrType)
            {
                throw Error.Argument("navigationProperty", SRResources.PropertyDoesNotBelongToType);
            }

            PropertyConfiguration           propertyConfig;
            NavigationPropertyConfiguration navigationPropertyConfig;

            if (ExplicitProperties.ContainsKey(navigationProperty))
            {
                propertyConfig = ExplicitProperties[navigationProperty];
                if (propertyConfig.Kind != PropertyKind.Navigation)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustBeNavigationProperty, navigationProperty.Name);
                }

                navigationPropertyConfig = propertyConfig as NavigationPropertyConfiguration;
                if (navigationPropertyConfig.Multiplicity != multiplicity)
                {
                    throw Error.Argument("navigationProperty", SRResources.MustHaveMatchingMultiplicity, navigationProperty.Name, multiplicity);
                }
            }
            else
            {
                navigationPropertyConfig = new NavigationPropertyConfiguration(navigationProperty, multiplicity);
                ExplicitProperties[navigationProperty] = navigationPropertyConfig;
                // make sure the related type is configured
                ModelBuilder.AddEntity(navigationPropertyConfig.RelatedClrType);
            }
            return(navigationPropertyConfig);
        }
        internal NavigationPropertyConfiguration GetOrCreateContainedNavigationProperty(Expression navigationPropertyExpression, EdmMultiplicity multiplicity)
        {
            PropertyInfo navigationProperty = PropertySelectorVisitor.GetSelectedProperty(navigationPropertyExpression);

            return(_configuration.AddContainedNavigationProperty(navigationProperty, multiplicity));
        }
 private void CheckNavigationMultiplicity(IEdmNavigationProperty navigation, EdmMultiplicity navigationMultiplicity, EdmMultiplicity navigationPartnerMultiplicity)
 {
     Assert.AreEqual(navigationMultiplicity, navigation.Partner.TargetMultiplicity(), "Invalid navigation property multiplicity.");
     Assert.AreEqual(navigationPartnerMultiplicity, navigation.TargetMultiplicity(), "Invalid navigation property partner multiplicity.");
 }
 /// <summary>
 /// Adds a contained EDM navigation property to this entity type.
 /// </summary>
 /// <param name="navigationProperty">The backing CLR property.</param>
 /// <param name="multiplicity">The <see cref="EdmMultiplicity"/> of the navigation property.</param>
 /// <returns>Returns the <see cref="NavigationPropertyConfiguration"/> of the added property.</returns>
 public virtual NavigationPropertyConfiguration AddContainedNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)
 {
     return AddNavigationProperty(navigationProperty, multiplicity, containsTarget: true);
 }
        private void CheckNavigationWithMultiplicityRecursiveContainmentEnd(IEdmModel model, EdmMultiplicity multiplicity)
        {
            this.CheckEntityTypeNavigationCount(model, "NS.Person", 6);
            var personNavigations = model.FindEntityType("NS.Person").NavigationProperties();

            var manyFriendToPerson = personNavigations.Where(n => n.Name.Equals("ManyFriendToPerson")).First();
            this.CheckNavigationContainment(manyFriendToPerson, false, true);
            this.CheckNavigationMultiplicity(manyFriendToPerson, EdmMultiplicity.Many, multiplicity);

            var zeroOrOneFriendToPerson = personNavigations.Where(n => n.Name.Equals("ZeroOrOneFriendToPerson")).First();
            this.CheckNavigationContainment(zeroOrOneFriendToPerson, false, true);
            this.CheckNavigationMultiplicity(zeroOrOneFriendToPerson, EdmMultiplicity.ZeroOrOne, multiplicity);

            var oneFriendToPerson = personNavigations.Where(n => n.Name.Equals("OneFriendToPerson")).First();
            this.CheckNavigationContainment(oneFriendToPerson, false, true);
            this.CheckNavigationMultiplicity(oneFriendToPerson, EdmMultiplicity.One, multiplicity);

            var toManyFriend = personNavigations.Where(n => n.Name.Equals("ToManyFriend")).First();
            this.CheckNavigationsArePartners(manyFriendToPerson, toManyFriend);

            var toZeroOrOneFriend = personNavigations.Where(n => n.Name.Equals("ToZeroOrOneFriend")).First();
            this.CheckNavigationsArePartners(zeroOrOneFriendToPerson, toZeroOrOneFriend);

            var toOneFriend = personNavigations.Where(n => n.Name.Equals("ToOneFriend")).First();
            this.CheckNavigationsArePartners(oneFriendToPerson, toOneFriend);
        }