/// <summary>
        /// Returns the association information for the specified navigation property.
        /// </summary>
        /// <param name="navigationProperty">The navigation property to return association information for</param>
        /// <returns>The association info</returns>
        internal AssociationInfo GetAssociationInfo(NavigationProperty navigationProperty)
        {
            return _associationMap.GetOrAdd(navigationProperty.RelationshipType.FullName, associationName =>
            {
                AssociationType associationType = (AssociationType)navigationProperty.RelationshipType;

                if (!associationType.ReferentialConstraints.Any())
                {
                    // We only support EF models where FK info is part of the model.
                    throw Error.NotSupported(Resource.LinqToEntitiesProvider_UnableToRetrieveAssociationInfo, associationName);
                }

                string toRoleName = associationType.ReferentialConstraints[0].ToRole.Name;
                AssociationInfo associationInfo = new AssociationInfo()
                {
                    FKRole = toRoleName,
                    Name = GetAssociationName(navigationProperty, toRoleName),
                    ThisKey = associationType.ReferentialConstraints[0].ToProperties.Select(p => p.Name).ToArray(),
                    OtherKey = associationType.ReferentialConstraints[0].FromProperties.Select(p => p.Name).ToArray(),
                    IsRequired = associationType.RelationshipEndMembers[0].RelationshipMultiplicity == RelationshipMultiplicity.One
                };

                return associationInfo;
            });
        }
        public void Can_get_and_set_configuration_facet()
        {
            var navigationProperty = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)));
            navigationProperty.SetConfiguration(42);

            Assert.Equal(42, navigationProperty.GetConfiguration());
        }
        public void Apply_is_noop_when_existing_constraint()
        {
            var associationType = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace);
            associationType.SourceEnd = new AssociationEndMember("S", new EntityType("E", "N", DataSpace.CSpace));
            associationType.TargetEnd = new AssociationEndMember("T", new EntityType("E", "N", DataSpace.CSpace));

            var property = EdmProperty.Primitive("Fk", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String));

            var associationConstraint
                = new ReferentialConstraint(
                    associationType.SourceEnd,
                    associationType.TargetEnd,
                    new[] { property },
                    new[] { property });

            associationType.Constraint = associationConstraint;

            var navigationProperty = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)))
                                         {
                                             RelationshipType = associationType
                                         };

            ((IEdmConvention<NavigationProperty>)new ForeignKeyNavigationPropertyAttributeConvention())
                .Apply(navigationProperty, new EdmModel(DataSpace.CSpace));

            Assert.Same(associationConstraint, navigationProperty.Association.Constraint);
        }
 public IEnumerable<IFilterAttribute> AttributesFor(NavigationProperty property)
 {
     return withCache(new Signature(property), () =>
     {
         var info = mapper.Map(property);
         return info.GetAttributes<IFilterAttribute>();
     });
 }
Beispiel #5
0
 internal void WriteNavigationPropertyElementHeader(NavigationProperty member)
 {
     _xmlWriter.WriteStartElement(XmlConstants.NavigationProperty);
     _xmlWriter.WriteAttributeString(XmlConstants.Name, member.Name);
     _xmlWriter.WriteAttributeString(
         XmlConstants.Relationship,
         GetQualifiedTypeName(XmlConstants.Self, member.Association.Name));
     _xmlWriter.WriteAttributeString(XmlConstants.FromRole, member.GetFromEnd().Name);
     _xmlWriter.WriteAttributeString(XmlConstants.ToRole, member.ToEndMember.Name);
 }
Beispiel #6
0
        internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo)
        {
            IEnumerable <EdmRelationshipNavigationPropertyAttribute> customAttributes = propertyInfo.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(false);
            EdmType edmType;

            if (!this.TryGetLoadedType(propertyInfo.PropertyType, out edmType) || edmType.BuiltInTypeKind != BuiltInTypeKind.EntityType && edmType.BuiltInTypeKind != BuiltInTypeKind.CollectionType)
            {
                this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_OSpace_InvalidNavPropReturnType((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyInfo.PropertyType.FullName)));
            }
            else
            {
                EdmRelationshipNavigationPropertyAttribute propertyAttribute = customAttributes.First <EdmRelationshipNavigationPropertyAttribute>();
                EdmMember member = (EdmMember)null;
                EdmType   type;
                if (this.SessionData.TypesInLoading.TryGetValue(propertyAttribute.RelationshipNamespaceName + "." + propertyAttribute.RelationshipName, out type) && Helper.IsAssociationType(type))
                {
                    AssociationType associationType = (AssociationType)type;
                    if (associationType != null)
                    {
                        NavigationProperty navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(edmType));
                        navigationProperty.RelationshipType = (RelationshipType)associationType;
                        member = (EdmMember)navigationProperty;
                        if (associationType.Members[0].Name == propertyAttribute.TargetRoleName)
                        {
                            navigationProperty.ToEndMember   = (RelationshipEndMember)associationType.Members[0];
                            navigationProperty.FromEndMember = (RelationshipEndMember)associationType.Members[1];
                        }
                        else if (associationType.Members[1].Name == propertyAttribute.TargetRoleName)
                        {
                            navigationProperty.ToEndMember   = (RelationshipEndMember)associationType.Members[1];
                            navigationProperty.FromEndMember = (RelationshipEndMember)associationType.Members[0];
                        }
                        else
                        {
                            this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.TargetRoleNameInNavigationPropertyNotValid((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyAttribute.TargetRoleName, (object)propertyAttribute.RelationshipName)));
                            member = (EdmMember)null;
                        }
                        if (member != null && ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType)
                        {
                            this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.NavigationPropertyRelationshipEndTypeMismatch((object)declaringType.FullName, (object)navigationProperty.Name, (object)associationType.FullName, (object)navigationProperty.FromEndMember.Name, (object)((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType)));
                            member = (EdmMember)null;
                        }
                    }
                }
                else
                {
                    this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.RelationshipNameInNavigationPropertyNotValid((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyAttribute.RelationshipName)));
                }
                if (member == null)
                {
                    return;
                }
                declaringType.AddMember(member);
            }
        }
        public void Apply_is_noop_when_no_fk_annotation()
        {
            var navigationProperty = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)))
                                         {
                                             RelationshipType = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace)
                                         };

            ((IEdmConvention<NavigationProperty>)new ForeignKeyNavigationPropertyAttributeConvention())
                .Apply(navigationProperty, new EdmModel(DataSpace.CSpace));

            Assert.Null(navigationProperty.Association.Constraint);
        }
        public void Configure_should_set_configuration_annotations()
        {
            var navigationPropertyConfiguration = new NavigationPropertyConfiguration(new MockPropertyInfo());
            var navigationProperty = new NavigationProperty("N", TypeUsage.Create(new EntityType()))
                                         {
                                             RelationshipType = new AssociationType()
                                         };

            navigationProperty.Association.SourceEnd = new AssociationEndMember("S", new EntityType());
            navigationProperty.Association.TargetEnd = new AssociationEndMember("T", new EntityType());

            navigationPropertyConfiguration.Configure(navigationProperty, new EdmModel(), new EntityTypeConfiguration(typeof(object)));

            Assert.NotNull(navigationProperty.GetConfiguration());
            Assert.NotNull(navigationProperty.Association.GetConfiguration());
        }
        public void EdmNavigationProperty_BadNavigationPropertyBadFromRoleType()
        {
            var parentEntity = new EntityType("P", "N", DataSpace.CSpace);
            var targetEntity = new EntityType("T", "N", DataSpace.CSpace);
            var sourceEntity = new EntityType("S", "N", DataSpace.CSpace);

            var associationType
                = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace)
                {
                SourceEnd = new AssociationEndMember("S", sourceEntity),
                TargetEnd = new AssociationEndMember("T", targetEntity)
                };

            var navigationProperty
                = new NavigationProperty("N", TypeUsage.Create(targetEntity))
                {
                RelationshipType = associationType
                };

            parentEntity.AddMember(navigationProperty);

            var model = new EdmModel(DataSpace.CSpace);

            model.AddItem(parentEntity);

            var validationContext
                = new EdmModelValidationContext(model, true);

            DataModelErrorEventArgs errorEventArgs = null;

            validationContext.OnError += (_, e) => errorEventArgs = e;

            EdmModelSemanticValidationRules
            .EdmNavigationProperty_BadNavigationPropertyBadFromRoleType
            .Evaluate(validationContext, navigationProperty);

            Assert.NotNull(errorEventArgs);
            Assert.Same(navigationProperty, errorEventArgs.Item);
            Assert.Equal(
                Strings.BadNavigationPropertyBadFromRoleType(
                    navigationProperty.Name,
                    sourceEntity.Name,
                    navigationProperty.GetFromEnd().Name,
                    navigationProperty.Association.Name,
                    parentEntity.Name),
                errorEventArgs.ErrorMessage);
        }
Beispiel #10
0
        /// <summary>
        ///     Creates a NavigationProperty instance from the specified parameters.
        /// </summary>
        /// <param name="name">The name of the navigation property.</param>
        /// <param name="typeUsage">Specifies the navigation property type and its facets.</param>
        /// <param name="relationshipType">The relationship type for the navigation.</param>
        /// <param name="from">The source end member in the navigation.</param>
        /// <param name="to">The target end member in the navigation.</param>
        /// <returns>The newly created NavigationProperty instance.</returns>
        public static NavigationProperty Create(
            string name,
            TypeUsage typeUsage,
            RelationshipType relationshipType,
            RelationshipEndMember from,
            RelationshipEndMember to)
        {
            var instance = new NavigationProperty(name, typeUsage);

            instance.RelationshipType = relationshipType;
            instance.FromEndMember    = from;
            instance.ToEndMember      = to;

            instance.SetReadOnly();

            return(instance);
        }
        public IFluentConfiguration Discover(NavigationProperty navigationProperty, DbModel model)
        {
            Debug.Assert(navigationProperty != null, "navigationProperty is null.");
            Debug.Assert(model != null, "model is null.");

            var associationType = (AssociationType)navigationProperty.RelationshipType;

            if (!associationType.IsForeignKey
                || (navigationProperty.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many
                    && navigationProperty.FromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many))
            {
                // Doesn't apply
                return null;
            }

            var constraint = associationType.Constraint;
            var entityType = (EntityType)navigationProperty.DeclaringType;
            var fromProperty = constraint.FromProperties.First();
            var fromPropertyName = fromProperty.Name;
            var toEntityType = navigationProperty.ToEndMember.GetEntityType();
            // NOTE: OrderBy works around a bug in primary key column ordering (Work Item 868)
            var toProperties = constraint.ToProperties.OrderBy(
                p => entityType.KeyMembers.IndexOf(constraint.FromProperties[constraint.ToProperties.IndexOf(p)]));
            var toPropertyName = toProperties.First().Name;

            if (!toProperties.MoreThan(1)
                && (toPropertyName.EqualsIgnoreCase(navigationProperty.Name + fromPropertyName)
                    || (!entityType.NavigationProperties.Where(p => p.ToEndMember.GetEntityType() == toEntityType)
                            .MoreThan(1)
                        && (toPropertyName.EqualsIgnoreCase(fromPropertyName)
                            || toPropertyName.EqualsIgnoreCase(fromProperty.DeclaringType.Name + fromPropertyName)))))
            {

                // By convention
                return null;
            }

            var configuration = new ForeignKeyConfiguration();

            foreach (var property in toProperties)
            {
                configuration.Properties.Add(property);
            }

            return configuration;
        }
 internal bool TryGetNavigationProperty(
     string relationshipType,
     string fromName,
     string toName,
     out NavigationProperty navigationProperty)
 {
     foreach (NavigationProperty navigationProperty1 in this.NavigationProperties)
     {
         if (navigationProperty1.RelationshipType.FullName == relationshipType && navigationProperty1.FromEndMember.Name == fromName && navigationProperty1.ToEndMember.Name == toName)
         {
             navigationProperty = navigationProperty1;
             return(true);
         }
     }
     navigationProperty = (NavigationProperty)null;
     return(false);
 }
        public void EdmNavigationProperty_BadNavigationPropertyBadFromRoleType()
        {
            var parentEntity = new EntityType("P", "N", DataSpace.CSpace);
            var targetEntity = new EntityType("T", "N", DataSpace.CSpace);
            var sourceEntity = new EntityType("S", "N", DataSpace.CSpace);

            var associationType
                = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace)
                      {
                          SourceEnd = new AssociationEndMember("S", sourceEntity),
                          TargetEnd = new AssociationEndMember("T", targetEntity)
                      };

            var navigationProperty
                = new NavigationProperty("N", TypeUsage.Create(targetEntity))
                      {
                          RelationshipType = associationType
                      };

            parentEntity.AddMember(navigationProperty);

            var model = new EdmModel(DataSpace.CSpace);

            model.AddItem(parentEntity);

            var validationContext
                = new EdmModelValidationContext(model, true);

            DataModelErrorEventArgs errorEventArgs = null;
            validationContext.OnError += (_, e) => errorEventArgs = e;

            EdmModelSemanticValidationRules
                .EdmNavigationProperty_BadNavigationPropertyBadFromRoleType
                .Evaluate(validationContext, navigationProperty);

            Assert.NotNull(errorEventArgs);
            Assert.Same(navigationProperty, errorEventArgs.Item);
            Assert.Equal(
                Strings.BadNavigationPropertyBadFromRoleType(
                    navigationProperty.Name,
                    sourceEntity.Name,
                    navigationProperty.GetFromEnd().Name,
                    navigationProperty.Association.Name,
                    parentEntity.Name),
                errorEventArgs.ErrorMessage);
        }
        public void Configure_should_set_configuration_annotations()
        {
            var navigationPropertyConfiguration = new NavigationPropertyConfiguration(new MockPropertyInfo(typeof(AType1), "N"));
            var navigationProperty = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)))
                                         {
                                             RelationshipType = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace)
                                         };

            navigationProperty.Association.SourceEnd = new AssociationEndMember("S", new EntityType("E", "N", DataSpace.CSpace));
            navigationProperty.Association.TargetEnd = new AssociationEndMember("T", new EntityType("E", "N", DataSpace.CSpace));

            navigationPropertyConfiguration.Configure(
                navigationProperty, new EdmModel(DataSpace.CSpace), new EntityTypeConfiguration(typeof(object)));

            Assert.NotNull(navigationProperty.GetConfiguration());
            Assert.NotNull(navigationProperty.Association.GetConfiguration());
        }
        public void Apply_is_noop_when_unknown_dependent()
        {
            var model = new EdmModel(DataSpace.CSpace);
            var associationType = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace);
            associationType.SourceEnd = new AssociationEndMember("S", new EntityType("E", "N", DataSpace.CSpace));
            associationType.TargetEnd = new AssociationEndMember("T", new EntityType("E", "N", DataSpace.CSpace));
            var navigationProperty = new NavigationProperty("N", TypeUsage.Create(associationType.TargetEnd.GetEntityType()))
                                         {
                                             RelationshipType = associationType
                                         };
            var foreignKeyAnnotation = new ForeignKeyAttribute("AId");
            navigationProperty.Annotations.SetClrAttributes(new[] { foreignKeyAnnotation });

            ((IEdmConvention<NavigationProperty>)new ForeignKeyNavigationPropertyAttributeConvention())
                .Apply(navigationProperty, model);

            Assert.Null(associationType.Constraint);
        }
        /// <summary>
        /// Creates an AssociationAttribute for the specified navigation property
        /// </summary>
        /// <param name="navigationProperty">The navigation property that corresponds to the association (it identifies the end points)</param>
        /// <returns>A new AssociationAttribute that describes the given navigation property association</returns>
        internal AssociationAttribute CreateAssociationAttribute(NavigationProperty navigationProperty)
        {
            var assocInfo = GetAssociationInfo(navigationProperty);
            var isForeignKey = navigationProperty.FromEndMember.Name == assocInfo.FKRole;
            string thisKey;
            string otherKey;
            if (isForeignKey) {
                thisKey = String.Join(",", assocInfo.ThisKey);
                otherKey = String.Join(",", assocInfo.OtherKey);
            }
            else {
                otherKey = String.Join(",", assocInfo.ThisKey);
                thisKey = String.Join(",", assocInfo.OtherKey);
            }

            return new AssociationAttribute(assocInfo.Name, thisKey, otherKey) {
                IsForeignKey = isForeignKey
            };
        }
        private static NavigationProperty ConvertToNavigationProperty(
            EntityType declaringEntityType,
            System.Data.Entity.Core.SchemaObjectModel.NavigationProperty somNavigationProperty,
            DbProviderManifest providerManifest,
            Converter.ConversionCache convertedItemCache,
            Dictionary <SchemaElement, GlobalItem> newGlobalItems)
        {
            EntityType       endMemberType   = (EntityType)Converter.LoadSchemaElement(somNavigationProperty.Type, providerManifest, convertedItemCache, newGlobalItems);
            AssociationType  associationType = (AssociationType)Converter.LoadSchemaElement((System.Data.Entity.Core.SchemaObjectModel.SchemaType)somNavigationProperty.Relationship, providerManifest, convertedItemCache, newGlobalItems);
            IRelationshipEnd end             = (IRelationshipEnd)null;

            somNavigationProperty.Relationship.TryGetEnd(somNavigationProperty.ToEnd.Name, out end);
            RelationshipMultiplicity?multiplicity1 = end.Multiplicity;
            EdmType edmType = (multiplicity1.GetValueOrDefault() != RelationshipMultiplicity.Many ? 0 : (multiplicity1.HasValue ? 1 : 0)) == 0 ? (EdmType)endMemberType : (EdmType)endMemberType.GetCollectionType();
            RelationshipMultiplicity?multiplicity2 = end.Multiplicity;
            TypeUsage typeUsage;

            if ((multiplicity2.GetValueOrDefault() != RelationshipMultiplicity.One ? 0 : (multiplicity2.HasValue ? 1 : 0)) != 0)
            {
                typeUsage = TypeUsage.Create(edmType, new FacetValues()
                {
                    Nullable = (FacetValueContainer <bool?>) new bool?(false)
                });
            }
            else
            {
                typeUsage = TypeUsage.Create(edmType);
            }
            Converter.InitializeAssociationEndMember(associationType, somNavigationProperty.ToEnd, endMemberType);
            Converter.InitializeAssociationEndMember(associationType, somNavigationProperty.FromEnd, declaringEntityType);
            NavigationProperty navigationProperty = new NavigationProperty(somNavigationProperty.Name, typeUsage);

            navigationProperty.RelationshipType = (RelationshipType)associationType;
            navigationProperty.ToEndMember      = (RelationshipEndMember)associationType.Members[somNavigationProperty.ToEnd.Name];
            navigationProperty.FromEndMember    = (RelationshipEndMember)associationType.Members[somNavigationProperty.FromEnd.Name];
            if (somNavigationProperty.Documentation != null)
            {
                navigationProperty.Documentation = Converter.ConvertToDocumentation(somNavigationProperty.Documentation);
            }
            Converter.AddOtherContent((SchemaElement)somNavigationProperty, (MetadataItem)navigationProperty);
            return(navigationProperty);
        }
        public void Nullability_updated_when_property_goes_readonly()
        {
            var navigationProperty 
                = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)))
                                         {
                                             ToEndMember =
                                                 new AssociationEndMember(
                                                 "T", new RefType(new EntityType("E", "N", DataSpace.CSpace)), RelationshipMultiplicity.ZeroOrOne)
                                         };

            Assert.Equal(true, navigationProperty.TypeUsage.Facets[EdmConstants.Nullable].Value);

            navigationProperty.ToEndMember.RelationshipMultiplicity = RelationshipMultiplicity.One;

            Assert.Equal(true, navigationProperty.TypeUsage.Facets[EdmConstants.Nullable].Value);

            navigationProperty.SetReadOnly();

            Assert.Equal(false, navigationProperty.TypeUsage.Facets[EdmConstants.Nullable].Value);
        }
Beispiel #19
0
        public void Nullability_updated_when_property_goes_readonly()
        {
            var navigationProperty
                = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)))
                {
                ToEndMember =
                    new AssociationEndMember(
                        "T", new RefType(new EntityType("E", "N", DataSpace.CSpace)), RelationshipMultiplicity.ZeroOrOne)
                };

            Assert.Equal(true, navigationProperty.TypeUsage.Facets[EdmConstants.Nullable].Value);

            navigationProperty.ToEndMember.RelationshipMultiplicity = RelationshipMultiplicity.One;

            Assert.Equal(true, navigationProperty.TypeUsage.Facets[EdmConstants.Nullable].Value);

            navigationProperty.SetReadOnly();

            Assert.Equal(false, navigationProperty.TypeUsage.Facets[EdmConstants.Nullable].Value);
        }
Beispiel #20
0
        private void ConfigureDependentBehavior(
            AssociationType associationType,
            EdmModel model,
            EntityTypeConfiguration entityTypeConfiguration)
        {
            AssociationEndMember principalEnd;
            AssociationEndMember dependentEnd;

            if (!associationType.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd))
            {
                if (this.IsNavigationPropertyDeclaringTypePrincipal.HasValue)
                {
                    associationType.MarkPrincipalConfigured();
                    System.Data.Entity.Core.Metadata.Edm.NavigationProperty navigationProperty = model.EntityTypes.SelectMany <EntityType, System.Data.Entity.Core.Metadata.Edm.NavigationProperty>((Func <EntityType, IEnumerable <System.Data.Entity.Core.Metadata.Edm.NavigationProperty> >)(et => (IEnumerable <System.Data.Entity.Core.Metadata.Edm.NavigationProperty>)et.DeclaredNavigationProperties)).Single <System.Data.Entity.Core.Metadata.Edm.NavigationProperty>((Func <System.Data.Entity.Core.Metadata.Edm.NavigationProperty, bool>)(np =>
                    {
                        if (np.RelationshipType.Equals((object)associationType))
                        {
                            return(np.GetClrPropertyInfo().IsSameAs(this.NavigationProperty));
                        }
                        return(false);
                    }));
                    principalEnd = this.IsNavigationPropertyDeclaringTypePrincipal.Value ? associationType.GetOtherEnd(navigationProperty.ResultEnd) : navigationProperty.ResultEnd;
                    dependentEnd = associationType.GetOtherEnd(principalEnd);
                    if (associationType.SourceEnd != principalEnd)
                    {
                        associationType.SourceEnd = principalEnd;
                        associationType.TargetEnd = dependentEnd;
                        AssociationSet associationSet = model.Containers.SelectMany <EntityContainer, AssociationSet>((Func <EntityContainer, IEnumerable <AssociationSet> >)(ct => (IEnumerable <AssociationSet>)ct.AssociationSets)).Single <AssociationSet>((Func <AssociationSet, bool>)(aset => aset.ElementType == associationType));
                        EntitySet      sourceSet      = associationSet.SourceSet;
                        associationSet.SourceSet = associationSet.TargetSet;
                        associationSet.TargetSet = sourceSet;
                    }
                }
                if (principalEnd == null)
                {
                    dependentEnd = associationType.TargetEnd;
                }
            }
            this.ConfigureConstraint(associationType, dependentEnd, entityTypeConfiguration);
            this.ConfigureDeleteAction(associationType.GetOtherEnd(dependentEnd));
        }
Beispiel #21
0
 // <summary>
 // Attempts to get the property name for the association between the two given end
 // names.  Note that this property may not exist if a navigation property is defined
 // in one direction but not in the other.
 // </summary>
 // <param name="relationshipType"> the relationship for which a nav property is required </param>
 // <param name="fromName"> the 'from' end of the association </param>
 // <param name="toName"> the 'to' end of the association </param>
 // <param name="navigationProperty"> the property name, or null if none was found </param>
 // <returns> true if a property was found, false otherwise </returns>
 internal bool TryGetNavigationProperty(
     string relationshipType, string fromName, string toName, out NavigationProperty navigationProperty)
 {
     // This is a linear search but it's probably okay because the number of entries
     // is generally small and this method is only called to generate code during lightweight
     // code gen.
     foreach (var navProperty in NavigationProperties)
     {
         if (navProperty.RelationshipType.FullName == relationshipType
             &&
             navProperty.FromEndMember.Name == fromName
             &&
             navProperty.ToEndMember.Name == toName)
         {
             navigationProperty = navProperty;
             return(true);
         }
     }
     navigationProperty = null;
     return(false);
 }
Beispiel #22
0
        internal void Configure(
            System.Data.Entity.Core.Metadata.Edm.NavigationProperty navigationProperty,
            EdmModel model,
            EntityTypeConfiguration entityTypeConfiguration)
        {
            navigationProperty.SetConfiguration((object)this);
            AssociationType association = navigationProperty.Association;
            NavigationPropertyConfiguration configuration = association.GetConfiguration() as NavigationPropertyConfiguration;

            if (configuration == null)
            {
                association.SetConfiguration((object)this);
            }
            else
            {
                this.EnsureConsistency(configuration);
            }
            this.ConfigureInverse(association, model);
            this.ConfigureEndKinds(association, configuration);
            this.ConfigureDependentBehavior(association, model, entityTypeConfiguration);
        }
        public static MultiplicityConfiguration Discover(NavigationProperty navigationProperty, out bool isDefault)
        {
            Debug.Assert(navigationProperty != null, "navigationProperty is null.");

            var entityType = (EntityType)navigationProperty.DeclaringType;
            var otherEntityType = navigationProperty.ToEndMember.GetEntityType();
            var otherNavigationProperty = otherEntityType.NavigationProperties.First(
                p => p.ToEndMember == navigationProperty.FromEndMember);

            isDefault = (navigationProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
                    || otherNavigationProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
                && !entityType.NavigationProperties.Where(p => p.ToEndMember.GetEntityType() == otherEntityType)
                    .MoreThan(1);

            return new MultiplicityConfiguration
                {
                    LeftEntityType = entityType,
                    LeftNavigationProperty = navigationProperty,
                    RightNavigationProperty = otherNavigationProperty
                };
        }
        public void Can_get_list_of_declared_navigation_properties()
        {
            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            Assert.Empty(entityType.DeclaredNavigationProperties);

            var property = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)));

            entityType.AddMember(property);

            Assert.Equal(1, entityType.DeclaredNavigationProperties.Count);

            entityType.RemoveMember(property);

            var baseType = new EntityType("E", "N", DataSpace.CSpace);
            baseType.AddMember(property);

            entityType.BaseType = baseType;

            Assert.Empty(entityType.DeclaredNavigationProperties);
            Assert.Equal(1, entityType.Members.Count);
        }
Beispiel #25
0
        public void NavigationProperties_is_thread_safe()
        {
            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            var property = new NavigationProperty("N", TypeUsage.Create(new EntityType("E", "N", DataSpace.CSpace)));

            entityType.AddMember(property);

            const int cycles      = 100;
            const int threadCount = 30;

            Action readNavigationProperties = () =>
            {
                for (var i = 0; i < cycles; ++i)
                {
                    var navProps = entityType.NavigationProperties;

                    //touching Members.Source triggers a reset to NavigationProperties
                    var sourceCount = entityType.Members.Source.Count;
                    Assert.True(sourceCount == 1);

                    var navigationPropertiesAfterReset = entityType.NavigationProperties;

                    Assert.True(navProps != null, "First reference to NavigationProperties should not be null");
                    Assert.True(navigationPropertiesAfterReset != null, "Second reference to NavigationProperties should not be null");
                    Assert.False(ReferenceEquals(navProps, navigationPropertiesAfterReset), "The NavigationProperties instances should be different");
                }
            };

            var tasks = new List <Thread>();

            for (var i = 0; i < threadCount; ++i)
            {
                tasks.Add(new Thread(new ThreadStart(readNavigationProperties)));
            }

            tasks.ForEach(t => t.Start());
            tasks.ForEach(t => t.Join());
        }
Beispiel #26
0
        public static void Adding_a_NavigationProperty_to_an_EntityType_can_be_forced_when_read_only()
        {
            var typeUsage       = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String));
            var associationType = new AssociationType("AssociationType", "Namespace", true, DataSpace.CSpace);
            var source          = new EntityType("Source", "Namespace", DataSpace.CSpace);
            var target          = new EntityType("Target", "Namespace", DataSpace.CSpace);
            var sourceEnd       = new AssociationEndMember("SourceEnd", source);
            var targetEnd       = new AssociationEndMember("TargetEnd", target);

            var navigationProperty =
                NavigationProperty.Create(
                    "NavigationProperty",
                    typeUsage,
                    associationType,
                    sourceEnd,
                    targetEnd,
                    null);

            source.SetReadOnly();
            Assert.True(source.IsReadOnly);

            Assert.Equal(
                Resources.Strings.OperationOnReadOnlyItem,
                Assert.Throws <InvalidOperationException>(
                    () => source.AddMember(navigationProperty)).Message);

            Assert.Equal(0, source.Members.Count);

            source.AddNavigationProperty(navigationProperty);

            Assert.True(source.IsReadOnly);
            Assert.Equal(1, source.Members.Count);
            Assert.Same(navigationProperty, source.Members[0]);

            Assert.Equal(
                Resources.Strings.OperationOnReadOnlyItem,
                Assert.Throws <InvalidOperationException>(
                    () => source.AddMember(navigationProperty)).Message);
        }
        /// <summary>
        /// Creates a NavigationProperty instance from the specified parameters.
        /// </summary>
        /// <param name="name">The name of the navigation property.</param>
        /// <param name="typeUsage">Specifies the navigation property type and its facets.</param>
        /// <param name="relationshipType">The relationship type for the navigation.</param>
        /// <param name="from">The source end member in the navigation.</param>
        /// <param name="to">The target end member in the navigation.</param>
        /// <param name="metadataProperties">The metadata properties of the navigation property.</param>
        /// <returns>The newly created NavigationProperty instance.</returns>
        public static NavigationProperty Create(
            string name,
            TypeUsage typeUsage,
            RelationshipType relationshipType,
            RelationshipEndMember from,
            RelationshipEndMember to,
            IEnumerable <MetadataProperty> metadataProperties)
        {
            Check.NotEmpty(name, nameof(name));
            Check.NotNull <TypeUsage>(typeUsage, nameof(typeUsage));
            NavigationProperty navigationProperty = new NavigationProperty(name, typeUsage);

            navigationProperty.RelationshipType = relationshipType;
            navigationProperty.FromEndMember    = from;
            navigationProperty.ToEndMember      = to;
            if (metadataProperties != null)
            {
                navigationProperty.AddMetadataProperties(metadataProperties.ToList <MetadataProperty>());
            }
            navigationProperty.SetReadOnly();
            return(navigationProperty);
        }
Beispiel #28
0
        public void Can_get_list_of_declared_navigation_properties()
        {
            var entityType = new EntityType();

            Assert.Empty(entityType.DeclaredNavigationProperties);

            var property = new NavigationProperty("N", TypeUsage.Create(new EntityType()));

            entityType.AddMember(property);

            Assert.Equal(1, entityType.DeclaredNavigationProperties.Count);

            entityType.RemoveMember(property);

            var baseType = new EntityType();

            baseType.AddMember(property);

            entityType.BaseType = baseType;

            Assert.Empty(entityType.DeclaredNavigationProperties);
            Assert.Equal(1, entityType.Members.Count);
        }
Beispiel #29
0
 private void ConfigureInverse(AssociationType associationType, EdmModel model)
 {
     if (this._inverseNavigationProperty == (PropertyInfo)null)
     {
         return;
     }
     System.Data.Entity.Core.Metadata.Edm.NavigationProperty navigationProperty = model.GetNavigationProperty(this._inverseNavigationProperty);
     if (navigationProperty == null || navigationProperty.Association == associationType)
     {
         return;
     }
     associationType.SourceEnd.RelationshipMultiplicity = navigationProperty.Association.TargetEnd.RelationshipMultiplicity;
     if (associationType.Constraint == null && this._constraint == null && navigationProperty.Association.Constraint != null)
     {
         associationType.Constraint          = navigationProperty.Association.Constraint;
         associationType.Constraint.FromRole = (RelationshipEndMember)associationType.SourceEnd;
         associationType.Constraint.ToRole   = (RelationshipEndMember)associationType.TargetEnd;
     }
     model.RemoveAssociationType(navigationProperty.Association);
     navigationProperty.RelationshipType = (RelationshipType)associationType;
     navigationProperty.FromEndMember    = (RelationshipEndMember)associationType.TargetEnd;
     navigationProperty.ToEndMember      = (RelationshipEndMember)associationType.SourceEnd;
 }
        private bool TryFindNavigationProperties(
            Type type,
            StructuralType cspaceType,
            StructuralType ospaceType,
            IEnumerable <PropertyInfo> clrProperties,
            List <Action> referenceResolutionListForCurrentType)
        {
            List <KeyValuePair <NavigationProperty, PropertyInfo> > keyValuePairList = new List <KeyValuePair <NavigationProperty, PropertyInfo> >();

            foreach (NavigationProperty declaredOnlyMember in cspaceType.GetDeclaredOnlyMembers <NavigationProperty>())
            {
                NavigationProperty cspaceProperty = declaredOnlyMember;
                PropertyInfo       propertyInfo   = clrProperties.FirstOrDefault <PropertyInfo>((Func <PropertyInfo, bool>)(p => OSpaceTypeFactory.NonPrimitiveMemberMatchesByConvention(p, (EdmMember)cspaceProperty)));
                if (propertyInfo != (PropertyInfo)null)
                {
                    bool flag = cspaceProperty.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many;
                    if (propertyInfo.CanRead && (!flag || propertyInfo.CanWriteExtended()))
                    {
                        keyValuePairList.Add(new KeyValuePair <NavigationProperty, PropertyInfo>(cspaceProperty, propertyInfo));
                    }
                }
                else
                {
                    this.LogLoadMessage(Strings.Validator_OSpace_Convention_MissingRequiredProperty((object)cspaceProperty.Name, (object)type.FullName), (EdmType)cspaceType);
                    return(false);
                }
            }
            foreach (KeyValuePair <NavigationProperty, PropertyInfo> keyValuePair in keyValuePairList)
            {
                this.TrackClosure(keyValuePair.Value.PropertyType);
                StructuralType     ct = cspaceType;
                StructuralType     ot = ospaceType;
                NavigationProperty cp = keyValuePair.Key;
                referenceResolutionListForCurrentType.Add((Action)(() => this.CreateAndAddNavigationProperty(ct, ot, cp)));
            }
            return(true);
        }
        public IFluentConfiguration Discover(NavigationProperty navigationProperty, DbModel model)
        {
            Debug.Assert(navigationProperty != null, "navigationProperty is null.");
            Debug.Assert(model != null, "model is null.");

            var fromEndMember = navigationProperty.FromEndMember;
            var toEndMember = navigationProperty.ToEndMember;

            if (fromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
                && toEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
            {
                // Doesn't apply
                return null;
            }

            var deleteBehavior = fromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many
                    && toEndMember.RelationshipMultiplicity != RelationshipMultiplicity.One
                ? fromEndMember.DeleteBehavior
                : toEndMember.DeleteBehavior;

            var defaultDeleteBehavior =
                (((fromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One
                                && toEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
                            || (fromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
                                && toEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One))
                        && fromEndMember.GetEntityType() != toEndMember.GetEntityType())
                    ? OperationAction.Cascade
                    : OperationAction.None;

            if (deleteBehavior == defaultDeleteBehavior)
            {
                // By convention
                return null;
            }

            return new CascadeDeleteConfiguration { DeleteBehavior = deleteBehavior };
        }
Beispiel #32
0
        public static void Create_sets_properties_and_seals_the_instance()
        {
            var typeUsage       = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String));
            var associationType = new AssociationType("AssociationType", "Namespace", true, DataSpace.CSpace);
            var source          = new EntityType("Source", "Namespace", DataSpace.CSpace);
            var target          = new EntityType("Target", "Namespace", DataSpace.CSpace);
            var sourceEnd       = new AssociationEndMember("SourceEnd", source);
            var targetEnd       = new AssociationEndMember("TargetEnd", target);

            var navigationProperty =
                NavigationProperty.Create(
                    "NavigationProperty",
                    typeUsage,
                    associationType,
                    sourceEnd,
                    targetEnd,
                    new[]
            {
                new MetadataProperty(
                    "TestProperty",
                    TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)),
                    "value"),
            });

            Assert.Equal("NavigationProperty", navigationProperty.Name);
            Assert.Same(typeUsage, navigationProperty.TypeUsage);
            Assert.Same(associationType, navigationProperty.RelationshipType);
            Assert.Same(sourceEnd, navigationProperty.FromEndMember);
            Assert.Same(targetEnd, navigationProperty.ToEndMember);
            Assert.True(navigationProperty.IsReadOnly);

            var metadataProperty = navigationProperty.MetadataProperties.SingleOrDefault(p => p.Name == "TestProperty");

            Assert.NotNull(metadataProperty);
            Assert.Equal("value", metadataProperty.Value);
        }
        public static void Create_sets_properties_and_seals_the_instance()
        {
            var typeUsage       = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String));
            var associationType = new AssociationType("AssociationType", "Namespace", true, DataSpace.CSpace);
            var source          = new EntityType("Source", "Namespace", DataSpace.CSpace);
            var target          = new EntityType("Target", "Namespace", DataSpace.CSpace);
            var sourceEnd       = new AssociationEndMember("SourceEnd", source);
            var targetEnd       = new AssociationEndMember("TargetEnd", target);

            var navigationProperty =
                NavigationProperty.Create(
                    "NavigationProperty",
                    typeUsage,
                    associationType,
                    sourceEnd,
                    targetEnd);

            Assert.Equal("NavigationProperty", navigationProperty.Name);
            Assert.Same(typeUsage, navigationProperty.TypeUsage);
            Assert.Same(associationType, navigationProperty.RelationshipType);
            Assert.Same(sourceEnd, navigationProperty.FromEndMember);
            Assert.Same(targetEnd, navigationProperty.ToEndMember);
            Assert.True(navigationProperty.IsReadOnly);
        }
Beispiel #34
0
 /// <summary>
 ///     Attempts to get the property name for the assoication between the two given end
 ///     names.  Note that this property may not exist if a navigation property is defined
 ///     in one direction but not in the other.
 /// </summary>
 /// <param name="relationshipType"> the relationship for which a nav property is required </param>
 /// <param name="fromName"> the 'from' end of the association </param>
 /// <param name="toName"> the 'to' end of the association </param>
 /// <param name="navigationProperty"> the property name, or null if none was found </param>
 /// <returns> true if a property was found, false otherwise </returns>
 internal bool TryGetNavigationProperty(
     string relationshipType, string fromName, string toName, out NavigationProperty navigationProperty)
 {
     // This is a linear search but it's probably okay because the number of entries
     // is generally small and this method is only called to generate code during lighweight
     // code gen.
     foreach (var navProperty in NavigationProperties)
     {
         if (navProperty.RelationshipType.FullName == relationshipType
             &&
             navProperty.FromEndMember.Name == fromName
             &&
             navProperty.ToEndMember.Name == toName)
         {
             navigationProperty = navProperty;
             return true;
         }
     }
     navigationProperty = null;
     return false;
 }
 public void AddNavigationProperty(NavigationProperty property)
 {
     AddMember(property, true);
 }
        /// <summary>
        /// Creates a NavigationProperty instance from the specified parameters.
        /// </summary>
        /// <param name="name">The name of the navigation property.</param>
        /// <param name="typeUsage">Specifies the navigation property type and its facets.</param>
        /// <param name="relationshipType">The relationship type for the navigation.</param>
        /// <param name="from">The source end member in the navigation.</param>
        /// <param name="to">The target end member in the navigation.</param>
        /// <param name="metadataProperties">The metadata properties of the navigation property.</param>
        /// <returns>The newly created NavigationProperty instance.</returns>
        public static NavigationProperty Create(
            string name,
            TypeUsage typeUsage,
            RelationshipType relationshipType,
            RelationshipEndMember from,
            RelationshipEndMember to,
            IEnumerable<MetadataProperty> metadataProperties)
        {
            Check.NotEmpty(name, "name");
            Check.NotNull(typeUsage, "typeUsage");

            var instance = new NavigationProperty(name, typeUsage);

            instance.RelationshipType = relationshipType;
            instance.FromEndMember = from;
            instance.ToEndMember = to;

            if (metadataProperties != null)
            {
                instance.AddMetadataProperties(metadataProperties.ToList());
            }

            instance.SetReadOnly();

            return instance;
        }
        private static bool IsModifed(NavigationProperty navigationProperty, IEnumerable<string> modifiedMembers)
        {
            var association = navigationProperty.RelationshipType as AssociationType;
            if (association == null)
                return false;

            var referentialConstraint = association.ReferentialConstraints.FirstOrDefault();
            if (referentialConstraint == null)
                return false;

            var toProperties = referentialConstraint
                .ToProperties
                .Select(p => p.Name)
                .ToList();

            return modifiedMembers.Intersect(toProperties).Any();
        }
        private static bool IsLoaded(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor accessor)
        {
            var relationshipManager = state.ObjectStateEntry.RelationshipManager;
            var getEntityReference = _relatedAccessor.Value.MakeGenericMethod(accessor.MemberType);
            var parameters = new[]
            {
                navigationProperty.RelationshipType.FullName,
                navigationProperty.ToEndMember.Name
            };

            var entityReference = getEntityReference.Invoke(relationshipManager, parameters) as EntityReference;
            return (entityReference != null && entityReference.IsLoaded);
        }
        internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo)
        {
            // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute and EdmRelationshipNavigationPropertyAttribute
            // are all EdmPropertyAttributes that we need to process. If the current property is not an EdmPropertyAttribute
            // we will just ignore it and skip to the next property.
            var relationshipPropertyAttributes = propertyInfo.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(inherit: false);

            Debug.Assert(relationshipPropertyAttributes.Count() == 1, "There should be exactly one property for every navigation property");

            // The only valid return types from navigation properties are:
            //     (1) EntityType
            //     (2) CollectionType containing valid EntityType

            // If TryGetLoadedType returned false, it could mean that we couldn't validate any part of the type, or it could mean that it's a generic
            // where the main generic type was validated, but the generic type parameter was not. We can't tell the difference, so just fail
            // with the same error message in both cases. The user will have to figure out which part of the type is wrong.
            // We can't just rely on checking for a generic because it can lead to a scenario where we report that the type parameter is invalid
            // when really it's the main generic type. That is more confusing than reporting the full name and letting the user determine the problem.
            EdmType propertyType;

            if (!TryGetLoadedType(propertyInfo.PropertyType, out propertyType)
                ||
                !(propertyType.BuiltInTypeKind == BuiltInTypeKind.EntityType ||
                  propertyType.BuiltInTypeKind == BuiltInTypeKind.CollectionType))
            {
                // Once an error is detected the property does not need to be validated further, just add to the errors
                // collection and continue with the next property. The failure will cause an exception to be thrown later during validation of all of the types.
                SessionData.EdmItemErrors.Add(
                    new EdmItemError(
                        Strings.Validator_OSpace_InvalidNavPropReturnType(
                            propertyInfo.Name, propertyInfo.DeclaringType.FullName, propertyInfo.PropertyType.FullName)));
                return;
            }
            // else we have a valid EntityType or CollectionType that contains EntityType. ResolveNonSchemaType enforces that a collection type
            // must contain an EntityType, and if it doesn't, propertyType will be null here. If propertyType is EntityType or CollectionType we know it is valid

            // Expecting EdmRelationshipNavigationPropertyAttribute to have AllowMultiple=False, so only look at first element in the attribute array

            var attribute = (EdmRelationshipNavigationPropertyAttribute)relationshipPropertyAttributes.First();

            EdmMember member = null;
            EdmType   type;

            if (SessionData.TypesInLoading.TryGetValue(attribute.RelationshipNamespaceName + "." + attribute.RelationshipName, out type)
                &&
                Helper.IsAssociationType(type))
            {
                var relationshipType = (AssociationType)type;
                if (relationshipType != null)
                {
                    // The return value of this property has been verified, so create the property now
                    var navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(propertyType));
                    navigationProperty.RelationshipType = relationshipType;
                    member = navigationProperty;

                    if (relationshipType.Members[0].Name
                        == attribute.TargetRoleName)
                    {
                        navigationProperty.ToEndMember   = (RelationshipEndMember)relationshipType.Members[0];
                        navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[1];
                    }
                    else if (relationshipType.Members[1].Name
                             == attribute.TargetRoleName)
                    {
                        navigationProperty.ToEndMember   = (RelationshipEndMember)relationshipType.Members[1];
                        navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[0];
                    }
                    else
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.TargetRoleNameInNavigationPropertyNotValid(
                                    propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.TargetRoleName,
                                    attribute.RelationshipName)));
                        member = null;
                    }

                    if (member != null
                        &&
                        ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType)
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.NavigationPropertyRelationshipEndTypeMismatch(
                                    declaringType.FullName,
                                    navigationProperty.Name,
                                    relationshipType.FullName,
                                    navigationProperty.FromEndMember.Name,
                                    ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType)));
                        member = null;
                    }
                }
            }
            else
            {
                SessionData.EdmItemErrors.Add(
                    new EdmItemError(
                        Strings.RelationshipNameInNavigationPropertyNotValid(
                            propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.RelationshipName)));
            }

            if (member != null)
            {
                declaringType.AddMember(member);
            }
        }
 protected override void VisitEdmNavigationProperty(NavigationProperty item)
 {
     _schemaWriter.WriteNavigationPropertyElementHeader(item);
     base.VisitEdmNavigationProperty(item);
     _schemaWriter.WriteEndElement();
 }
Beispiel #41
0
        public void AddNavigationProperty(NavigationProperty property)
        {
            Check.NotNull(property, "property");

            AddMember(property, true);
        }
Beispiel #42
0
        private void CreateAndAddNavigationProperty(
            StructuralType cspaceType, StructuralType ospaceType, NavigationProperty cspaceProperty)
        {
            EdmType ospaceRelationship;

            if (CspaceToOspace.TryGetValue(cspaceProperty.RelationshipType, out ospaceRelationship))
            {
                Debug.Assert(ospaceRelationship is StructuralType, "Structural type expected.");

                var     foundTarget = false;
                EdmType targetType  = null;
                if (Helper.IsCollectionType(cspaceProperty.TypeUsage.EdmType))
                {
                    EdmType findType;
                    foundTarget =
                        CspaceToOspace.TryGetValue(
                            ((CollectionType)cspaceProperty.TypeUsage.EdmType).TypeUsage.EdmType, out findType);
                    if (foundTarget)
                    {
                        Debug.Assert(findType is StructuralType, "Structural type expected.");

                        targetType = findType.GetCollectionType();
                    }
                }
                else
                {
                    EdmType findType;
                    foundTarget = CspaceToOspace.TryGetValue(cspaceProperty.TypeUsage.EdmType, out findType);
                    if (foundTarget)
                    {
                        Debug.Assert(findType is StructuralType, "Structural type expected.");

                        targetType = findType;
                    }
                }

                Debug.Assert(
                    foundTarget,
                    "Since the relationship will only be created if it can find the types for both ends, we will never fail to find one of the ends");

                var navigationProperty = new NavigationProperty(cspaceProperty.Name, TypeUsage.Create(targetType));
                var relationshipType   = (RelationshipType)ospaceRelationship;
                navigationProperty.RelationshipType = relationshipType;

                // we can use First because o-space relationships are created directly from
                // c-space relationship
                navigationProperty.ToEndMember =
                    (RelationshipEndMember)relationshipType.Members.First(e => e.Name == cspaceProperty.ToEndMember.Name);
                navigationProperty.FromEndMember =
                    (RelationshipEndMember)relationshipType.Members.First(e => e.Name == cspaceProperty.FromEndMember.Name);
                ospaceType.AddMember(navigationProperty);
            }
            else
            {
                var missingType =
                    cspaceProperty.RelationshipType.RelationshipEndMembers.Select(e => ((RefType)e.TypeUsage.EdmType).ElementType).First(
                        e => e != cspaceType);
                LogError(
                    Strings.Validator_OSpace_Convention_RelationshipNotLoaded(
                        cspaceProperty.RelationshipType.FullName, missingType.FullName),
                    missingType);
            }
        }
 /// <summary>
 ///     Constrcut a new member mapping metadata object
 /// </summary>
 /// <param name="edmNavigationProperty"> </param>
 /// <param name="clrNavigationProperty"> </param>
 internal ObjectNavigationPropertyMapping(NavigationProperty edmNavigationProperty, NavigationProperty clrNavigationProperty)
     :
         base(edmNavigationProperty, clrNavigationProperty)
 {
 }
 protected virtual void Visit(NavigationProperty navigationProperty)
 {
     Visit(navigationProperty.FromEndMember);
     Visit(navigationProperty.RelationshipType);
     Visit(navigationProperty.ToEndMember);
     Visit(navigationProperty.TypeUsage);
 }
 public void AddNavigationProperty(NavigationProperty property)
 {
     Check.NotNull <NavigationProperty>(property, nameof(property));
     this.AddMember((EdmMember)property, true);
 }
        private void CreateAndAddNavigationProperty(
            StructuralType cspaceType, StructuralType ospaceType, NavigationProperty cspaceProperty)
        {
            EdmType ospaceRelationship;
            if (CspaceToOspace.TryGetValue(cspaceProperty.RelationshipType, out ospaceRelationship))
            {
                Debug.Assert(ospaceRelationship is StructuralType, "Structural type expected.");

                var foundTarget = false;
                EdmType targetType = null;
                if (Helper.IsCollectionType(cspaceProperty.TypeUsage.EdmType))
                {
                    EdmType findType;
                    foundTarget =
                        CspaceToOspace.TryGetValue(
                            ((CollectionType)cspaceProperty.TypeUsage.EdmType).TypeUsage.EdmType, out findType);
                    if (foundTarget)
                    {
                        Debug.Assert(findType is StructuralType, "Structural type expected.");

                        targetType = findType.GetCollectionType();
                    }
                }
                else
                {
                    EdmType findType;
                    foundTarget = CspaceToOspace.TryGetValue(cspaceProperty.TypeUsage.EdmType, out findType);
                    if (foundTarget)
                    {
                        Debug.Assert(findType is StructuralType, "Structural type expected.");

                        targetType = findType;
                    }
                }

                Debug.Assert(
                    foundTarget,
                    "Since the relationship will only be created if it can find the types for both ends, we will never fail to find one of the ends");

                var navigationProperty = new NavigationProperty(cspaceProperty.Name, TypeUsage.Create(targetType));
                var relationshipType = (RelationshipType)ospaceRelationship;
                navigationProperty.RelationshipType = relationshipType;

                // we can use First because o-space relationships are created directly from 
                // c-space relationship
                navigationProperty.ToEndMember =
                    (RelationshipEndMember)relationshipType.Members.First(e => e.Name == cspaceProperty.ToEndMember.Name);
                navigationProperty.FromEndMember =
                    (RelationshipEndMember)relationshipType.Members.First(e => e.Name == cspaceProperty.FromEndMember.Name);
                ospaceType.AddMember(navigationProperty);
            }
            else
            {
                var missingType =
                    cspaceProperty.RelationshipType.RelationshipEndMembers.Select(e => ((RefType)e.TypeUsage.EdmType).ElementType).First(
                        e => e != cspaceType);
                LogError(
                    Strings.Validator_OSpace_Convention_RelationshipNotLoaded(
                        cspaceProperty.RelationshipType.FullName, missingType.FullName),
                    missingType);
            }
        }
        private Node RewriteNavigationProperty(
            NavigationProperty navProperty,
            Node sourceEntityNode, TypeUsage resultType)
        {
            var relProperty = new RelProperty(navProperty.RelationshipType, navProperty.FromEndMember, navProperty.ToEndMember);
            PlanCompiler.Assert(
                m_command.IsRelPropertyReferenced(relProperty)
                || (relProperty.ToEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many),
                "Unreferenced rel property? " + relProperty);

            // Handle N:1
            if ((relProperty.FromEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many)
                &&
                (relProperty.ToEnd.RelationshipMultiplicity != RelationshipMultiplicity.Many))
            {
                return RewriteManyToOneNavigationProperty(relProperty, sourceEntityNode, resultType);
            }

            //
            // Find the list of all relationships that could satisfy this relationship
            // If we find no matching relationship set, simply return a null node / empty collection
            //
            var relationshipSets = GetRelationshipSets(relProperty.Relationship);
            if (relationshipSets.Count == 0)
            {
                // return an empty set / null node
                if (relProperty.ToEnd.RelationshipMultiplicity
                    == RelationshipMultiplicity.Many)
                {
                    return m_command.CreateNode(m_command.CreateNewMultisetOp(resultType));
                }
                return m_command.CreateNode(m_command.CreateNullOp(resultType));
            }

            // Build out a ref over the source entity 
            var sourceRefNode = m_command.CreateNode(
                m_command.CreateGetEntityRefOp(relProperty.FromEnd.TypeUsage),
                sourceEntityNode);

            // Hanlde the 1:M and N:M cases
            if (relProperty.ToEnd.RelationshipMultiplicity
                == RelationshipMultiplicity.Many)
            {
                // Handle N:M
                if (relProperty.FromEnd.RelationshipMultiplicity
                    == RelationshipMultiplicity.Many)
                {
                    return RewriteManyToManyNavigationProperty(relProperty, relationshipSets, sourceRefNode);
                }
                // Handle 1:M
                return RewriteOneToManyNavigationProperty(relProperty, relationshipSets, sourceRefNode);
            }

            // Handle 1:1
            return RewriteOneToOneNavigationProperty(relProperty, relationshipSets, sourceRefNode);
        }
        internal void Configure(
            NavigationProperty navigationProperty, EdmModel model, EntityTypeConfiguration entityTypeConfiguration)
        {
            DebugCheck.NotNull(navigationProperty);
            DebugCheck.NotNull(model);
            DebugCheck.NotNull(entityTypeConfiguration);

            navigationProperty.SetConfiguration(this);

            var associationType = navigationProperty.Association;
            var configuration = associationType.GetConfiguration() as NavigationPropertyConfiguration;

            if (configuration == null)
            {
                associationType.SetConfiguration(this);
            }
            else
            {
                ValidateConsistency(configuration);
            }

            ConfigureInverse(associationType, model);
            ConfigureEndKinds(associationType, configuration);
            ConfigureDependentBehavior(associationType, model, entityTypeConfiguration);
        }
 /// <summary>
 ///     Utility method to retrieve the 'To' AssociationEndMember of a NavigationProperty
 /// </summary>
 /// <param name="property"> The navigation property </param>
 /// <returns> The AssociationEndMember that is the target of the navigation operation represented by the NavigationProperty </returns>
 private AssociationEndMember GetNavigationPropertyTargetEnd(NavigationProperty property)
 {
     var relationship = Metadata.GetItem<AssociationType>(property.RelationshipType.FullName, DataSpace.CSpace);
     Debug.Assert(
         relationship.AssociationEndMembers.Contains(property.ToEndMember.Name),
         "Association does not declare member referenced by Navigation property?");
     return relationship.AssociationEndMembers[property.ToEndMember.Name];
 }
 /// <summary>
 ///     Validate an NavigationProperty object
 /// </summary>
 /// <param name="item"> The NavigationProperty object to validate </param>
 /// <param name="errors"> An error collection for adding validation errors </param>
 /// <param name="validatedItems"> A dictionary keeping track of items that have been validated </param>
 private void ValidateNavigationProperty(NavigationProperty item, List <EdmItemError> errors, HashSet <MetadataItem> validatedItems)
 {
     // Continue to process the property to see if there are other errors. This allows the user to fix as much as possible at the same time.
     ValidateEdmMember(item, errors, validatedItems);
 }
Beispiel #51
0
        public void AddNavigationProperty(NavigationProperty property)
        {
            Check.NotNull(property, "property");

            AddMember(property, true);
        }
        private static string GetForeignKey(NavigationProperty navigationProperty)
        {
            var association = navigationProperty.RelationshipType as AssociationType;
            if (association == null)
                return null;

            // only support first constraint
            var referentialConstraint = association.ReferentialConstraints.FirstOrDefault();
            if (referentialConstraint == null)
                return null;

            var toProperties = referentialConstraint
              .ToProperties
              .Select(p => p.Name)
              .ToArray();

            return string.Join(",", toProperties);
        }
        private static object GetDisplayValue(AuditEntryState state, NavigationProperty navigationProperty, IMemberAccessor displayMember, DbDataRecord values)
        {
            if (values == null)
                return null;

            var association = navigationProperty.RelationshipType as AssociationType;
            if (association == null)
                return null;

            // only support first constraint
            var referentialConstraint = association.ReferentialConstraints.FirstOrDefault();
            if (referentialConstraint == null)
                return null;

            var toProperties = referentialConstraint
              .ToProperties
              .Select(p => p.Name)
              .ToList();

            var fromProperties = referentialConstraint
              .FromProperties
              .Select(p => p.Name)
              .ToList();

            // make sure key columns match
            if (fromProperties.Count != toProperties.Count)
                return null;

            var edmType = referentialConstraint
              .FromProperties
              .Select(p => p.DeclaringType)
              .FirstOrDefault();

            if (edmType == null)
                return null;

            var entitySet = state.ObjectContext.GetEntitySet(edmType.FullName);

            var sql = new StringBuilder();
            sql.Append("SELECT VALUE t.")
                .Append(displayMember.Name)
                .Append(" FROM ")
                .Append(entitySet.Name)
                .Append(" as t")
                .Append(" WHERE ");

            var parameters = new List<ObjectParameter>();
            for (int index = 0; index < fromProperties.Count; index++)
            {
                if (index > 0)
                    sql.Append(" AND ");

                string fromProperty = fromProperties[index];
                string toProperty = toProperties[index];
                var value = values.GetValue(toProperty);
                var name = "@" + fromProperty;

                sql.Append(" t.").Append(fromProperty);
                if (value != null)
                {
                    sql.Append(" == ").Append(name);
                    parameters.Add(new ObjectParameter(fromProperty, value));
                }
                else
                {
                    sql.Append(" is null");
                }
            }

            var q = state.ObjectContext.CreateQuery<object>(
                sql.ToString(),
                parameters.ToArray());

            return q.FirstOrDefault();
        }
        public void TranslateColumnMap_returns_correct_columntypes_and_nullablecolumns_for_associations()
        {
            var metadataWorkspaceMock = new Mock<MetadataWorkspace>();
            metadataWorkspaceMock.Setup(m => m.GetQueryCacheManager()).Returns(QueryCacheManager.Create());

            var codeFirstOSpaceTypeFactory = new CodeFirstOSpaceTypeFactory();
            var refEntityColumnMap = (EntityColumnMap)BuildSimpleEntitySetColumnMap(metadataWorkspaceMock, codeFirstOSpaceTypeFactory).Element;
            
            var cSpaceEntityType = new EntityType(typeof(RefEntity).Name, "N", DataSpace.CSpace);
            cSpaceEntityType.AddMember(new EdmProperty("Id", TypeUsage.Create(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))));

            var navigationProperty = new NavigationProperty("SimpleEntity", TypeUsage.Create(refEntityColumnMap.Type.EdmType));
            var associationType = new AssociationType("A", "N", false, DataSpace.CSpace);
            associationType.AddMember(
                new AssociationEndMember("From", new RefType(cSpaceEntityType), RelationshipMultiplicity.One));
            associationType.AddMember(
                new AssociationEndMember("To", new RefType((EntityType)navigationProperty.TypeUsage.EdmType), RelationshipMultiplicity.One));
            associationType.SetReadOnly();

            navigationProperty.RelationshipType = associationType;
            navigationProperty.FromEndMember = associationType.RelationshipEndMembers[0];
            navigationProperty.ToEndMember = associationType.RelationshipEndMembers[1];
            cSpaceEntityType.AddMember(navigationProperty);
            var entityTypeUsage = TypeUsage.Create(cSpaceEntityType);

            var oSpaceEntityType = codeFirstOSpaceTypeFactory.TryCreateType(typeof(RefEntity), cSpaceEntityType);
            codeFirstOSpaceTypeFactory.CspaceToOspace.Add(cSpaceEntityType, oSpaceEntityType);

            var associations = new EdmItemCollection();
            associations.AddInternal(associationType);

            codeFirstOSpaceTypeFactory.CreateRelationships(associations);
            foreach (var resolve in codeFirstOSpaceTypeFactory.ReferenceResolutions)
            {
                resolve();
            }

            var idScalarMap = new ScalarColumnMap(TypeUsage.Create(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)), "Id", 0, 1);
            var refColumnMap = new RefColumnMap(
                associationType.RelationshipEndMembers[1].TypeUsage, "E",
                new SimpleEntityIdentity(null, new SimpleColumnMap[] { idScalarMap }));
            var collectionMap = new SimpleCollectionColumnMap(
                entityTypeUsage, "MockCollectionType", refColumnMap, null, null);

            metadataWorkspaceMock.Setup(m => m.GetItem<EdmType>("N.RefEntity", DataSpace.OSpace))
                .Returns(oSpaceEntityType);

            var factory =
                new Translator().TranslateColumnMap<object>(
                    collectionMap, metadataWorkspaceMock.Object, new SpanIndex(), MergeOption.NoTracking, streaming: false, valueLayer: false);
            Assert.NotNull(factory);

            Assert.Equal(new[] { null, typeof(int) }, factory.ColumnTypes);
            Assert.Equal(new[] { false, true }, factory.NullableColumns);
        }
Beispiel #55
0
 protected override void VisitEdmNavigationProperty(NavigationProperty item)
 {
     this._schemaWriter.WriteNavigationPropertyElementHeader(item);
     base.VisitEdmNavigationProperty(item);
     this._schemaWriter.WriteEndElement();
 }