コード例 #1
0
        public void Can_get_and_set_constraint_via_wrapper_property()
        {
            var associationType
                = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace)
                      {
                          SourceEnd = new AssociationEndMember("S", new EntityType("E", "N", DataSpace.CSpace)),
                          TargetEnd = new AssociationEndMember("T", new EntityType("E", "N", DataSpace.CSpace))
                      };

            Assert.Null(associationType.Constraint);
            Assert.False(associationType.IsForeignKey);

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

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

            associationType.Constraint = referentialConstraint;

            Assert.Same(referentialConstraint, associationType.Constraint);
            Assert.True(associationType.IsForeignKey);
        }
        public void Apply_should_set_principal_end_kind_to_required_when_all_properties_not_nullable()
        {
            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));

            associationType.SourceEnd.RelationshipMultiplicity = RelationshipMultiplicity.ZeroOrOne;

            var property1 = EdmProperty.CreatePrimitive("P1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String));
            var property2 = EdmProperty.CreatePrimitive("P2", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String));

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

            associationConstraint.ToProperties.Each(p => p.Nullable = false);

            associationType.Constraint = associationConstraint;

            (new ForeignKeyAssociationMultiplicityConvention())
                .Apply(associationType, new DbModel(new EdmModel(DataSpace.CSpace), null));

            Assert.True(associationType.SourceEnd.IsRequired());
        }
コード例 #3
0
        internal ForeignKeyConstraint(RelationshipSet relationshipSet, ReferentialConstraint constraint)
        {
            var assocSet = relationshipSet as AssociationSet;
            var fromEnd = constraint.FromRole as AssociationEndMember;
            var toEnd = constraint.ToRole as AssociationEndMember;

            // Currently only Associations are supported
            if (null == assocSet || null == fromEnd
                || null == toEnd)
            {
                throw new NotSupportedException();
            }

            m_constraint = constraint;
            var parent = MetadataHelper.GetEntitySetAtEnd(assocSet, fromEnd);
            // relationshipSet.GetRelationshipEndExtent(constraint.FromRole);
            var child = MetadataHelper.GetEntitySetAtEnd(assocSet, toEnd); // relationshipSet.GetRelationshipEndExtent(constraint.ToRole);
            m_extentPair = new ExtentPair(parent, child);
            m_childKeys = new List<string>();
            foreach (var prop in constraint.ToProperties)
            {
                m_childKeys.Add(prop.Name);
            }

            m_parentKeys = new List<string>();
            foreach (var prop in constraint.FromProperties)
            {
                m_parentKeys.Add(prop.Name);
            }

            PlanCompiler.Assert(
                (RelationshipMultiplicity.ZeroOrOne == fromEnd.RelationshipMultiplicity
                 || RelationshipMultiplicity.One == fromEnd.RelationshipMultiplicity),
                "from-end of relationship constraint cannot have multiplicity greater than 1");
        }
        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 void Apply_should_transfer_constraint_and_clr_property_info_annotation()
        {
            EdmModel model
                = new TestModelBuilder()
                    .Entities("S", "T")
                    .Association("S", RelationshipMultiplicity.ZeroOrOne, "T", RelationshipMultiplicity.Many)
                    .Association("T", RelationshipMultiplicity.Many, "S", RelationshipMultiplicity.ZeroOrOne);

            var association2 = model.AssociationTypes.Last();

            var mockPropertyInfo = new MockPropertyInfo();
            association2.SourceEnd.SetClrPropertyInfo(mockPropertyInfo);

            var referentialConstraint 
                = new ReferentialConstraint(
                    association2.SourceEnd, 
                    association2.TargetEnd, 
                    new[] { new EdmProperty("P") }, 
                    new[] { new EdmProperty("D") });
            
            association2.Constraint = referentialConstraint;

            ((IEdmConvention)new AssociationInverseDiscoveryConvention()).Apply(model);

            Assert.Equal(1, model.AssociationTypes.Count());
            Assert.Equal(1, model.Containers.Single().AssociationSets.Count());

            var associationType = model.AssociationTypes.Single();

            Assert.NotSame(association2, associationType);
            Assert.Same(referentialConstraint, associationType.Constraint);
            Assert.Same(associationType.SourceEnd, referentialConstraint.FromRole);
            Assert.Same(associationType.TargetEnd, referentialConstraint.ToRole);
            Assert.Same(mockPropertyInfo.Object, associationType.TargetEnd.GetClrPropertyInfo());
        }
コード例 #6
0
        public void Create_throws_argument_exception_when_called_with_null_or_empty_arguments()
        {
            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 constraint =
                new ReferentialConstraint(
                    sourceEnd,
                    targetEnd,
                    new[] { new EdmProperty("SourceProperty") },
                    new[] { new EdmProperty("TargetProperty") });
            var associationType =
                AssociationType.Create(
                    "AssociationType",
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    Enumerable.Empty<MetadataProperty>());
            var sourceSet = new EntitySet("SourceSet", "Schema", "Table", "Query", source);
            var targetSet = new EntitySet("TargetSet", "Schema", "Table", "Query", target);
            var metadataProperty =
                new MetadataProperty(
                    "MetadataProperty",
                    TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)),
                    "value");

            // name is null
            Assert.Throws<ArgumentException>(
                () => AssociationSet.Create(
                    null,
                    associationType,
                    sourceSet,
                    targetSet,
                    new [] { metadataProperty }));

            // name is empty
            Assert.Throws<ArgumentException>(
                () => AssociationSet.Create(
                    String.Empty,
                    associationType,
                    sourceSet,
                    targetSet,
                    new[] { metadataProperty }));

            // type is null
            Assert.Throws<ArgumentNullException>(
                () => AssociationSet.Create(
                    "AssociationSet",
                    null,
                    sourceSet,
                    targetSet,
                    new[] { metadataProperty }));
        }
コード例 #7
0
        public void Create_throws_argument_exception_when_called_with_null_or_empty_arguments()
        {
            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 constraint =
                new ReferentialConstraint(
                    sourceEnd,
                    targetEnd,
                    new[] { new EdmProperty("SourceProperty") },
                    new[] { new EdmProperty("TargetProperty") });
            var associationType =
                AssociationType.Create(
                    "AssociationType",
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    Enumerable.Empty <MetadataProperty>());
            var sourceSet        = new EntitySet("SourceSet", "Schema", "Table", "Query", source);
            var targetSet        = new EntitySet("TargetSet", "Schema", "Table", "Query", target);
            var metadataProperty =
                new MetadataProperty(
                    "MetadataProperty",
                    TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)),
                    "value");

            // name is null
            Assert.Throws <ArgumentException>(
                () => AssociationSet.Create(
                    null,
                    associationType,
                    sourceSet,
                    targetSet,
                    new [] { metadataProperty }));

            // name is empty
            Assert.Throws <ArgumentException>(
                () => AssociationSet.Create(
                    String.Empty,
                    associationType,
                    sourceSet,
                    targetSet,
                    new[] { metadataProperty }));

            // type is null
            Assert.Throws <ArgumentNullException>(
                () => AssociationSet.Create(
                    "AssociationSet",
                    null,
                    sourceSet,
                    targetSet,
                    new[] { metadataProperty }));
        }
コード例 #8
0
 protected override void VisitEdmAssociationConstraint(ReferentialConstraint item)
 {
     _schemaWriter.WriteReferentialConstraintElementHeader();
     _schemaWriter.WriteReferentialConstraintRoleElement(
         XmlConstants.PrincipalRole, item.FromRole, item.FromProperties);
     _schemaWriter.WriteReferentialConstraintRoleElement(
         XmlConstants.DependentRole, item.ToRole, item.ToProperties);
     VisitMetadataItem(item);
     _schemaWriter.WriteEndElement();
 }
コード例 #9
0
        public void FromProperties_lazy_loaded_when_none_present()
        {
            var principalEntity = new EntityType("E", "N", DataSpace.CSpace);
            principalEntity.AddKeyMember(new EdmProperty("K"));

            var referentialConstraint
                = new ReferentialConstraint(
                    new AssociationEndMember("P", principalEntity),
                    new AssociationEndMember("D", new EntityType("E", "N", DataSpace.CSpace)),
                    Enumerable.Empty<EdmProperty>(),
                    Enumerable.Empty<EdmProperty>());

            Assert.NotEmpty(referentialConstraint.FromProperties);
        }
コード例 #10
0
        public void FromProperties_lazy_loaded_when_none_present()
        {
            var principalEntity = new EntityType("E", "N", DataSpace.CSpace);

            principalEntity.AddKeyMember(new EdmProperty("K"));

            var referentialConstraint
                = new ReferentialConstraint(
                      new AssociationEndMember("P", principalEntity),
                      new AssociationEndMember("D", new EntityType("E", "N", DataSpace.CSpace)),
                      Enumerable.Empty <EdmProperty>(),
                      Enumerable.Empty <EdmProperty>());

            Assert.NotEmpty(referentialConstraint.FromProperties);
        }
コード例 #11
0
        public void Create_sets_properties_and_seals_the_instance()
        {
            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 constraint =
                new ReferentialConstraint(
                    sourceEnd,
                    targetEnd,
                    new[] { new EdmProperty("SourceProperty") },
                    new[] { new EdmProperty("TargetProperty") });
            var associationType =
                AssociationType.Create(
                    "AssociationType",
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    Enumerable.Empty <MetadataProperty>());
            var sourceSet        = new EntitySet("SourceSet", "Schema", "Table", "Query", source);
            var targetSet        = new EntitySet("TargetSet", "Schema", "Table", "Query", target);
            var metadataProperty =
                new MetadataProperty(
                    "MetadataProperty",
                    TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)),
                    "value");
            var associationSet =
                AssociationSet.Create(
                    "AssociationSet",
                    associationType,
                    sourceSet,
                    targetSet,
                    new[] { metadataProperty });

            Assert.Equal("AssociationSet", associationSet.Name);
            Assert.Same(associationType, associationSet.ElementType);
            Assert.Same(sourceSet, associationSet.SourceSet);
            Assert.Same(targetSet, associationSet.TargetSet);
            Assert.Same(source, associationSet.SourceEnd.GetEntityType());
            Assert.Same(target, associationSet.TargetEnd.GetEntityType());
            Assert.Same(metadataProperty, associationSet.MetadataProperties.SingleOrDefault(p => p.Name == "MetadataProperty"));
            Assert.True(associationSet.IsReadOnly);
        }
コード例 #12
0
        public void Can_set_and_get_dependent_end()
        {
            var dependentEnd1 = new AssociationEndMember("D", new EntityType());

            var referentialConstraint
                = new ReferentialConstraint(
                    new AssociationEndMember("P", new EntityType()),
                    dependentEnd1,
                    new[] { EdmProperty.Primitive("P", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) },
                    new[] { EdmProperty.Primitive("D", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) });

            Assert.Same(dependentEnd1, referentialConstraint.DependentEnd);

            var dependentEnd2 = new AssociationEndMember("D2", new EntityType());

            referentialConstraint.DependentEnd = dependentEnd2;

            Assert.Same(dependentEnd2, referentialConstraint.DependentEnd);
        }
コード例 #13
0
        public void Can_set_and_get_to_role()
        {
            var toRole = new AssociationEndMember("D", new EntityType("E", "N", DataSpace.CSpace));

            var referentialConstraint
                = new ReferentialConstraint(
                    new AssociationEndMember("P", new EntityType("E", "N", DataSpace.CSpace)),
                    toRole,
                    new[] { EdmProperty.Primitive("P", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) },
                    new[] { EdmProperty.Primitive("D", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) });

            Assert.Same(toRole, referentialConstraint.ToRole);

            var toRole2 = new AssociationEndMember("D2", new EntityType("E", "N", DataSpace.CSpace));

            referentialConstraint.ToRole = toRole2;

            Assert.Same(toRole2, referentialConstraint.ToRole);
        }
コード例 #14
0
        private static AssociationType CreateCSpaceAssociationType(int index)
        {
            var sourceProperty = new EdmProperty("SourceProperty");
            var targetProperty = new EdmProperty("TargetProperty");

            var sourceEntityType = EntityType.Create(
                "SourceEntityType" + index,
                "Namespace",
                DataSpace.CSpace,
                new [] { "SourceProperty" },
                new[] { sourceProperty },
                Enumerable.Empty <MetadataProperty>());
            var targetEntityType = EntityType.Create(
                "TargetEntityType" + index,
                "Namespace",
                DataSpace.CSpace,
                new[] { "TargetProperty" },
                new[] { targetProperty },
                Enumerable.Empty <MetadataProperty>());

            var sourceEnd = new AssociationEndMember("SourceEnd" + index, sourceEntityType);
            var targetEnd = new AssociationEndMember("TargetEnd" + index, targetEntityType);

            var constraint =
                new ReferentialConstraint(
                    sourceEnd,
                    targetEnd,
                    new[] { sourceProperty },
                    new[] { targetProperty });

            var associationType =
                AssociationType.Create(
                    "AssociationType" + index,
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    Enumerable.Empty <MetadataProperty>());

            return(associationType);
        }
コード例 #15
0
        public void Can_set_and_get_dependent_end()
        {
            var dependentEnd1 = new AssociationEndMember("D", new EntityType());

            var referentialConstraint
                = new ReferentialConstraint(
                      new AssociationEndMember("P", new EntityType()),
                      dependentEnd1,
                      new[] { EdmProperty.Primitive("P", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) },
                      new[] { EdmProperty.Primitive("D", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) });

            Assert.Same(dependentEnd1, referentialConstraint.DependentEnd);

            var dependentEnd2 = new AssociationEndMember("D2", new EntityType());

            referentialConstraint.DependentEnd = dependentEnd2;

            Assert.Same(dependentEnd2, referentialConstraint.DependentEnd);
        }
コード例 #16
0
        public void Can_set_and_get_to_role()
        {
            var toRole = new AssociationEndMember("D", new EntityType("E", "N", DataSpace.CSpace));

            var referentialConstraint
                = new ReferentialConstraint(
                      new AssociationEndMember("P", new EntityType("E", "N", DataSpace.CSpace)),
                      toRole,
                      new[] { EdmProperty.Primitive("P", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) },
                      new[] { EdmProperty.Primitive("D", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)) });

            Assert.Same(toRole, referentialConstraint.ToRole);

            var toRole2 = new AssociationEndMember("D2", new EntityType("E", "N", DataSpace.CSpace));

            referentialConstraint.ToRole = toRole2;

            Assert.Same(toRole2, referentialConstraint.ToRole);
        }
コード例 #17
0
        public IEnumerable <EdmProperty> GetDependentProperties()
        {
            AssociationType relationshipType = (AssociationType)this.RelationshipType;

            if (relationshipType.ReferentialConstraints.Count > 0)
            {
                ReferentialConstraint referentialConstraint = relationshipType.ReferentialConstraints[0];
                if (referentialConstraint.ToRole.EdmEquals((MetadataItem)this.FromEndMember))
                {
                    ReadOnlyMetadataCollection <EdmMember> keyMembers = referentialConstraint.FromRole.GetEntityType().KeyMembers;
                    List <EdmProperty> edmPropertyList = new List <EdmProperty>(keyMembers.Count);
                    for (int index = 0; index < keyMembers.Count; ++index)
                    {
                        edmPropertyList.Add(referentialConstraint.ToProperties[referentialConstraint.FromProperties.IndexOf((EdmProperty)keyMembers[index])]);
                    }
                    return((IEnumerable <EdmProperty>) new ReadOnlyCollection <EdmProperty>((IList <EdmProperty>)edmPropertyList));
                }
            }
            return(Enumerable.Empty <EdmProperty>());
        }
コード例 #18
0
        public void BuildConstraintExceptionMessage_returns_message_for_single_property_constraint()
        {
            var principalType = new EntityType("Principal", "N", DataSpace.CSpace);
            var principalProperty = EdmProperty.CreatePrimitive("P1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));
            principalType.AddMember(principalProperty);

            var dependentType = new EntityType("Dependent", "N", DataSpace.CSpace);
            var dependentProperty = EdmProperty.CreatePrimitive("D1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));
            dependentType.AddMember(dependentProperty);

            var referentialConstraint
                = new ReferentialConstraint(
                    new AssociationEndMember("P", principalType),
                    new AssociationEndMember("D", dependentType),
                    new[] { principalProperty },
                    new[] { dependentProperty });

            Assert.Equal(
                Strings.RelationshipManager_InconsistentReferentialConstraintProperties("Principal.P1", "Dependent.D1"),
                referentialConstraint.BuildConstraintExceptionMessage());
        }
コード例 #19
0
        /// <summary>
        /// Creates a read-only AssociationType instance from the specified parameters.
        /// </summary>
        /// <param name="name">The name of the association type.</param>
        /// <param name="namespaceName">The namespace of the association type.</param>
        /// <param name="foreignKey">Flag that indicates a foreign key (FK) relationship.</param>
        /// <param name="dataSpace">The data space for the association type.</param>
        /// <param name="sourceEnd">The source association end member.</param>
        /// <param name="targetEnd">The target association end member.</param>
        /// <param name="constraint">A referential constraint.</param>
        /// <param name="metadataProperties">Metadata properties to be associated with the instance.</param>
        /// <returns>The newly created AssociationType instance.</returns>
        /// <exception cref="System.ArgumentException">The specified name is null or empty.</exception>
        /// <exception cref="System.ArgumentException">The specified namespace is null or empty.</exception>
        public static AssociationType Create(
            string name,
            string namespaceName,
            bool foreignKey,
            DataSpace dataSpace,
            AssociationEndMember sourceEnd,
            AssociationEndMember targetEnd,
            ReferentialConstraint constraint,
            IEnumerable <MetadataProperty> metadataProperties)
        {
            Check.NotEmpty(name, "name");
            Check.NotEmpty(namespaceName, "namespaceName");

            var instance = new AssociationType(name, namespaceName, foreignKey, dataSpace);

            if (sourceEnd != null)
            {
                instance.SourceEnd = sourceEnd;
            }

            if (targetEnd != null)
            {
                instance.TargetEnd = targetEnd;
            }

            if (constraint != null)
            {
                instance.AddReferentialConstraint(constraint);
            }

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

            instance.SetReadOnly();

            return(instance);
        }
コード例 #20
0
        public void Apply_should_not_discover_when_existing_constraint()
        {
            var associationType = new AssociationType();
            associationType.SourceEnd = new AssociationEndMember("S", new EntityType());
            associationType.TargetEnd = new AssociationEndMember("T", new EntityType());

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

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

            associationType.Constraint = associationConstraint;

            ((IEdmConvention<AssociationType>)new TypeNameForeignKeyDiscoveryConvention())
                .Apply(associationType, new EdmModel().Initialize());

            Assert.Same(associationConstraint, associationType.Constraint);
        }
        public void Apply_should_not_discover_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.CreatePrimitive("Fk", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String));

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

            associationType.Constraint = associationConstraint;

            (new TypeNameForeignKeyDiscoveryConvention())
                .Apply(associationType, new DbModel(new EdmModel(DataSpace.CSpace), null));

            Assert.Same(associationConstraint, associationType.Constraint);
        }
コード例 #22
0
        public void BuildConstraintExceptionMessage_returns_message_for_single_property_constraint()
        {
            var principalType     = new EntityType("Principal", "N", DataSpace.CSpace);
            var principalProperty = EdmProperty.CreatePrimitive("P1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));

            principalType.AddMember(principalProperty);

            var dependentType     = new EntityType("Dependent", "N", DataSpace.CSpace);
            var dependentProperty = EdmProperty.CreatePrimitive("D1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));

            dependentType.AddMember(dependentProperty);

            var referentialConstraint
                = new ReferentialConstraint(
                      new AssociationEndMember("P", principalType),
                      new AssociationEndMember("D", dependentType),
                      new[] { principalProperty },
                      new[] { dependentProperty });

            Assert.Equal(
                Strings.RelationshipManager_InconsistentReferentialConstraintProperties("Principal.P1", "Dependent.D1"),
                referentialConstraint.BuildConstraintExceptionMessage());
        }
コード例 #23
0
        public void Create_sets_properties_and_seals_the_instance()
        {
            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 constraint =
                new ReferentialConstraint(
                    sourceEnd,
                    targetEnd,
                    new[] { new EdmProperty("SourceProperty") },
                    new[] { new EdmProperty("TargetProperty") });
            var metadataProperty =
                new MetadataProperty(
                    "MetadataProperty",
                    TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)),
                    "value");
            var associationType =
                AssociationType.Create(
                    "AssociationType",
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    new[] { metadataProperty });

            Assert.Equal("Namespace.AssociationType", associationType.FullName);
            Assert.Equal(true, associationType.IsForeignKey);
            Assert.Equal(DataSpace.CSpace, associationType.DataSpace);
            Assert.Same(sourceEnd, associationType.SourceEnd);
            Assert.Same(targetEnd, associationType.TargetEnd);
            Assert.Same(constraint, associationType.Constraint);
            Assert.Same(metadataProperty, associationType.MetadataProperties.SingleOrDefault(p => p.Name == "MetadataProperty"));
            Assert.True(associationType.IsReadOnly);
        }
コード例 #24
0
        private static DbRelatedEntityRef RelatedEntityRefFromAssociationSetEnd(
            EntityType constructedEntityType, DbNewInstanceExpression entityConstructor, AssociationSetEnd principalSetEnd,
            ReferentialConstraint fkConstraint)
        {
            var principalEntityType = (EntityType)TypeHelpers.GetEdmType<RefType>(fkConstraint.FromRole.TypeUsage).ElementType;
            IList<DbExpression> principalKeyValues = null;

            // Create Entity Property/DbExpression value pairs from the entity constructor DbExpression,
            // then join these with the principal/dependent property pairs from the FK constraint
            // to produce principal property name/DbExpression value pairs from which to create the principal ref.
            //
            // Ideally the code would be as below, but anonymous types break asmmeta:
            //var keyPropAndValue =
            //    from pv in constructedEntityType.Properties.Select((p, idx) => new { DependentProperty = p, Value = entityConstructor.Arguments[idx] })
            //    join ft in fkConstraint.FromProperties.Select((fp, idx) => new { PrincipalProperty = fp, DependentProperty = fkConstraint.ToProperties[idx] })
            //    on pv.DependentProperty equals ft.DependentProperty
            //    select new { PrincipalProperty = ft.PrincipalProperty.Name, Value = pv.Value };
            //
            var keyPropAndValue =
                from pv in constructedEntityType.Properties.Select((p, idx) => Tuple.Create(p, entityConstructor.Arguments[idx]))
                // new { DependentProperty = p, Value = entityConstructor.Arguments[idx] })
                join ft in fkConstraint.FromProperties.Select((fp, idx) => Tuple.Create(fp, fkConstraint.ToProperties[idx]))
                    //new { PrincipalProperty = fp, DependentProperty = fkConstraint.ToProperties[idx] })
                    on pv.Item1 equals ft.Item2
                //pv.DependentProperty equals ft.DependentProperty
                select Tuple.Create(ft.Item1.Name, pv.Item2); // new { PrincipalProperty = ft.PrincipalProperty.Name, Value = pv.Value };

            // If there is only a single property in the principal's key, then there is no ordering concern.
            // Otherwise, create a dictionary of principal key property name to DbExpression value so that
            // when used as the arguments to the ref expression, the dependent property values - used here
            // as principal key property values - are in the correct order, which is the same order as the
            // key members themselves.
            //
            if (fkConstraint.FromProperties.Count == 1)
            {
                var singleKeyNameAndValue = keyPropAndValue.Single();
                Debug.Assert(singleKeyNameAndValue.Item1 == fkConstraint.FromProperties[0].Name, "Unexpected single key property name");
                principalKeyValues = new[] { singleKeyNameAndValue.Item2 };
            }
            else
            {
                var keyValueMap = keyPropAndValue.ToDictionary(pav => pav.Item1, pav => pav.Item2, StringComparer.Ordinal);
                principalKeyValues = principalEntityType.KeyMemberNames.Select(memberName => keyValueMap[memberName]).ToList();
            }

            // Create the ref to the principal entity based on the (now correctly ordered) key value expressions.
            //
            var principalRef = principalSetEnd.EntitySet.CreateRef(principalEntityType, principalKeyValues);
            var result = DbExpressionBuilder.CreateRelatedEntityRef(fkConstraint.ToRole, fkConstraint.FromRole, principalRef);

            return result;
        }
コード例 #25
0
        private static bool IsFKPartiallyContainedInPK(
            ReferentialConstraint constraint,
            string associationTypeName,
            IList<EdmSchemaError> errors)
        {
            var toType = (EntityType)constraint.ToProperties[0].DeclaringType;
            var toPropertiesAreFullyContainedInPK = true;
            var toPropertiesContainedAtLeastOnePK = false;

            foreach (var edmProperty in constraint.ToProperties)
            {
                // Check if there is at least one to property is not primary key.
                toPropertiesAreFullyContainedInPK &= toType.KeyMembers.Contains(edmProperty);
                // Check if there is one to property is primary key.
                toPropertiesContainedAtLeastOnePK |= toType.KeyMembers.Contains(edmProperty);
            }

            if (!toPropertiesAreFullyContainedInPK && toPropertiesContainedAtLeastOnePK)
            {
                var foreignKeys = MembersToCommaSeparatedString(constraint.ToProperties);
                var primaryKeys = MembersToCommaSeparatedString(toType.KeyMembers);

                errors.Add(
                    new EdmSchemaError(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            Resources_VersioningFacade.UnsupportedForeignKeyPattern,
                            associationTypeName,
                            foreignKeys,
                            primaryKeys,
                            toType.Name),
                        (int)ModelBuilderErrorCode.UnsupportedForeinKeyPattern,
                        EdmSchemaErrorSeverity.Warning));

                return true;
            }

            return false;
        }
コード例 #26
0
 private static bool AreAllEntityColumnsMappedAsToColumns(
     EntitySet storeEntitySet,
     ReferentialConstraint constraint0,
     ReferentialConstraint constraint1)
 {
     var names = new HashSet<string>(constraint0.ToProperties.Select(p => p.Name));
     names.UnionWith(constraint1.ToProperties.Select(p => p.Name));
     return names.Count == storeEntitySet.ElementType.Properties.Count;
 }
コード例 #27
0
 protected override void VisitEdmAssociationConstraint(ReferentialConstraint item)
 {
     _schemaWriter.WriteReferentialConstraintElementHeader();
     _schemaWriter.WriteReferentialConstraintRoleElement(
         XmlConstants.PrincipalRole,
         item.PrincipalEnd(_currentAssociationType),
         item.PrincipalEnd(_currentAssociationType).GetEntityType().GetValidKey());
     _schemaWriter.WriteReferentialConstraintRoleElement(
         XmlConstants.DependentRole, item.DependentEnd, item.ToProperties);
     VisitMetadataItem(item);
     _schemaWriter.WriteEndElement();
 }
コード例 #28
0
        // Check if related entities contain proper property values 
        internal override bool CheckReferentialConstraintPrincipalProperty(EntityEntry ownerEntry, ReferentialConstraint constraint)
        {
            EntityKey principalKey;
            if (!IsEmpty())
            {
                var wrappedRelatedEntity = ReferenceValue;
                // For Added entities, it doesn't matter what the key value is since it can't be trusted anyway.
                if (wrappedRelatedEntity.ObjectStateEntry != null
                    && wrappedRelatedEntity.ObjectStateEntry.State == EntityState.Added)
                {
                    return true;
                }
                principalKey = ExtractPrincipalKey(wrappedRelatedEntity);
            }
            else if ((ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne ||
                      ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
                     &&
                     DetachedEntityKey != null)
            {
                // Generally for foreign keys we want to use the EntityKey to do RI constraint validation
                // However, if we are doing an Add/Attach, we should use the DetachedEntityKey because this is the value
                // set by the user while the entity was detached, and should be used until the entity is fully added/attached
                if (IsForeignKey &&
                    !(ObjectContext.ObjectStateManager.TransactionManager.IsAddTracking ||
                      ObjectContext.ObjectStateManager.TransactionManager.IsAttachTracking))
                {
                    principalKey = EntityKey;
                }
                else
                {
                    principalKey = DetachedEntityKey;
                }
            }
            else
            {
                // We only need to check for RI constraints if the related end contains a real entity or is a reference with a detached entitykey
                return true;
            }

            return VerifyRIConstraintsWithRelatedEntry(constraint, ownerEntry.GetCurrentEntityValue, principalKey);
        }
コード例 #29
0
        internal override bool CheckReferentialConstraintDependentProperty(EntityEntry ownerEntry, ReferentialConstraint constraint)
        {
            // if the related end contains a real entity or is a reference with a detached entitykey, we need to check for RI constraints
            if (!IsEmpty())
            {
                return base.CheckReferentialConstraintDependentProperty(ownerEntry, constraint);
            }
            else if ((ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne ||
                      ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
                     &&
                     DetachedEntityKey != null)
            {
                // related end is empty, so we must have a reference with a detached key
                var detachedKey = DetachedEntityKey;
#if DEBUG
                // If the constraint is not PK<->PK then we can't validate it here.
                // This debug code checks that we don't try to validate it.
                var keyNames = new List<string>(
                    from v in detachedKey.EntityKeyValues
                    select v.Key);
                foreach (var prop in constraint.ToProperties)
                {
                    Debug.Assert(
                        keyNames.Contains(prop.Name),
                        "Attempt to validate constraint where some FK values are not in the dependent PK");
                }
#endif
                // don't need to validate the principal/detached key here because that has already been done during AttachContext
                if (!VerifyRIConstraintsWithRelatedEntry(constraint, detachedKey.FindValueByName, ownerEntry.EntityKey))
                {
                    return false;
                }
            }

            return true;
        }
コード例 #30
0
        private static AssociationType ConvertToAssociationType(
            Relationship element,
            DbProviderManifest providerManifest,
            Converter.ConversionCache convertedItemCache,
            Dictionary <SchemaElement, GlobalItem> newGlobalItems)
        {
            AssociationType associationType = new AssociationType(element.Name, element.Namespace, element.IsForeignKey, Converter.GetDataSpace(providerManifest));

            newGlobalItems.Add((SchemaElement)element, (GlobalItem)associationType);
            foreach (RelationshipEnd end in (IEnumerable <IRelationshipEnd>)element.Ends)
            {
                EntityType           endMemberType        = (EntityType)Converter.LoadSchemaElement((System.Data.Entity.Core.SchemaObjectModel.SchemaType)end.Type, providerManifest, convertedItemCache, newGlobalItems);
                AssociationEndMember associationEndMember = Converter.InitializeAssociationEndMember(associationType, (IRelationshipEnd)end, endMemberType);
                Converter.AddOtherContent((SchemaElement)end, (MetadataItem)associationEndMember);
                foreach (OnOperation operation in (IEnumerable <OnOperation>)end.Operations)
                {
                    if (operation.Operation == Operation.Delete)
                    {
                        OperationAction operationAction = OperationAction.None;
                        switch (operation.Action)
                        {
                        case System.Data.Entity.Core.SchemaObjectModel.Action.None:
                            operationAction = OperationAction.None;
                            break;

                        case System.Data.Entity.Core.SchemaObjectModel.Action.Cascade:
                            operationAction = OperationAction.Cascade;
                            break;
                        }
                        associationEndMember.DeleteBehavior = operationAction;
                    }
                }
                if (end.Documentation != null)
                {
                    associationEndMember.Documentation = Converter.ConvertToDocumentation(end.Documentation);
                }
            }
            for (int index = 0; index < element.Constraints.Count; ++index)
            {
                System.Data.Entity.Core.SchemaObjectModel.ReferentialConstraint constraint = element.Constraints[index];
                AssociationEndMember  member1               = (AssociationEndMember)associationType.Members[constraint.PrincipalRole.Name];
                AssociationEndMember  member2               = (AssociationEndMember)associationType.Members[constraint.DependentRole.Name];
                EntityTypeBase        elementType1          = ((RefType)member1.TypeUsage.EdmType).ElementType;
                EntityTypeBase        elementType2          = ((RefType)member2.TypeUsage.EdmType).ElementType;
                ReferentialConstraint referentialConstraint = new ReferentialConstraint((RelationshipEndMember)member1, (RelationshipEndMember)member2, (IEnumerable <EdmProperty>)Converter.GetProperties(elementType1, constraint.PrincipalRole.RoleProperties), (IEnumerable <EdmProperty>)Converter.GetProperties(elementType2, constraint.DependentRole.RoleProperties));
                if (constraint.Documentation != null)
                {
                    referentialConstraint.Documentation = Converter.ConvertToDocumentation(constraint.Documentation);
                }
                if (constraint.PrincipalRole.Documentation != null)
                {
                    referentialConstraint.FromRole.Documentation = Converter.ConvertToDocumentation(constraint.PrincipalRole.Documentation);
                }
                if (constraint.DependentRole.Documentation != null)
                {
                    referentialConstraint.ToRole.Documentation = Converter.ConvertToDocumentation(constraint.DependentRole.Documentation);
                }
                associationType.AddReferentialConstraint(referentialConstraint);
                Converter.AddOtherContent((SchemaElement)element.Constraints[index], (MetadataItem)referentialConstraint);
            }
            if (element.Documentation != null)
            {
                associationType.Documentation = Converter.ConvertToDocumentation(element.Documentation);
            }
            Converter.AddOtherContent((SchemaElement)element, (MetadataItem)associationType);
            return(associationType);
        }
コード例 #31
0
 private static bool IsAtLeastOneColumnFkInBothAssociations(
     ReferentialConstraint constraint0,
     ReferentialConstraint constraint1)
 {
     return constraint1.ToProperties.Any(p => constraint0.ToProperties.Contains(p));
 }
コード例 #32
0
        public void Create_throws_argument_exception_when_called_with_invalid_arguments()
        {
            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 constraint =
                new ReferentialConstraint(
                    sourceEnd,
                    targetEnd,
                    new[] { new EdmProperty("SourceProperty") },
                    new[] { new EdmProperty("TargetProperty") });
            var metadataProperty =
                new MetadataProperty(
                    "MetadataProperty",
                    TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)),
                    "value");

            Assert.Throws <ArgumentException>(
                () => AssociationType.Create(
                    null,
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    new[] { metadataProperty }));

            Assert.Throws <ArgumentException>(
                () => AssociationType.Create(
                    String.Empty,
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    new[] { metadataProperty }));

            Assert.Throws <ArgumentException>(
                () => AssociationType.Create(
                    "AssociationType",
                    null,
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    new[] { metadataProperty }));

            Assert.Throws <ArgumentException>(
                () => AssociationType.Create(
                    "AssociationType",
                    String.Empty,
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    new[] { metadataProperty }));
        }
コード例 #33
0
 private static bool IsAtLeastOneColumnOfBothDependentRelationshipColumnSetsNonNullable(
     ReferentialConstraint constraint0,
     ReferentialConstraint constraint1)
 {
     return constraint0.ToProperties.Any(p => !p.Nullable)
            && constraint1.ToProperties.Any(p => !p.Nullable);
 }
コード例 #34
0
        private static bool ValidateReferentialConstraint(
            ReferentialConstraint constraint,
            bool generateForeignKeyProperties,
            string associationTypeName,
            IEnumerable<AssociationType> associationTypes,
            IList<EdmSchemaError> errors)
        {
            if (constraint == null)
            {
                return false;
            }

            // We can skip validation checks if the FKs are directly surfaced (since we can produce valid mappings in these cases).
            if (generateForeignKeyProperties)
            {
                return true;
            }

            if (IsFKPartiallyContainedInPK(constraint, associationTypeName, errors))
            {
                return false;
            }

            // Check if any FK (which could also be a PK) is shared among multiple Associations (ie shared via foreign key constraint).
            // To do this we check if the AssociationType being generated has any dependent property which is also a dependent in one 
            // of the association typed already added. If so, we keep one association and throw the rest away.
            foreach (var toPropertyOfAddedAssociation in associationTypes.SelectMany(
                t => t.ReferentialConstraints.SelectMany(refconst => refconst.ToProperties)))
            {
                foreach (var toProperty in constraint.ToProperties)
                {
                    if (toProperty.DeclaringType.Equals(toPropertyOfAddedAssociation.DeclaringType)
                        && toProperty.Equals(toPropertyOfAddedAssociation))
                    {
                        errors.Add(
                            new EdmSchemaError(
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    Resources_VersioningFacade.SharedForeignKey,
                                    associationTypeName,
                                    toProperty,
                                    toProperty.DeclaringType),
                                (int)ModelBuilderErrorCode.SharedForeignKey,
                                EdmSchemaErrorSeverity.Warning));

                        return false;
                    }
                }
            }

            return true;
        }
コード例 #35
0
        protected override void Visit(ReferentialConstraint referentialConstraint)
        {
            int index;
            if (!AddObjectToSeenListAndHashBuilder(referentialConstraint, out index))
            {
                return;
            }

            AddObjectStartDumpToHashBuilder(referentialConstraint, index);

            #region Inner data visit

            AddObjectContentToHashBuilder(referentialConstraint.Identity);

            base.Visit(referentialConstraint);

            #endregion

            AddObjectEndDumpToHashBuilder();
        }
        internal override void Configure(
            AssociationType associationType,
            AssociationEndMember dependentEnd,
            EntityTypeConfiguration entityTypeConfiguration)
        {
            DebugCheck.NotNull(associationType);
            DebugCheck.NotNull(dependentEnd);
            DebugCheck.NotNull(entityTypeConfiguration);

            if (!_dependentProperties.Any())
            {
                return;
            }

            var dependentPropertInfos = _dependentProperties.AsEnumerable();

            if (!IsFullySpecified)
            {
                var foreignKeys
                    = from p in _dependentProperties
                      select new
                          {
                              PropertyInfo = p,
                              entityTypeConfiguration.Property(new PropertyPath(p)).ColumnOrder
                          };

                if ((_dependentProperties.Count > 1)
                    && foreignKeys.Any(p => !p.ColumnOrder.HasValue))
                {
                    var dependentKeys = dependentEnd.GetEntityType().KeyProperties;

                    if ((dependentKeys.Count == _dependentProperties.Count)
                        && foreignKeys.All(fk => dependentKeys.Any(p => p.GetClrPropertyInfo().IsSameAs(fk.PropertyInfo))))
                    {
                        // The FK and PK sets are equal, we know the order
                        dependentPropertInfos = dependentKeys.Select(p => p.GetClrPropertyInfo());
                    }
                    else
                    {
                        throw Error.ForeignKeyAttributeConvention_OrderRequired(entityTypeConfiguration.ClrType);
                    }
                }
                else
                {
                    dependentPropertInfos = foreignKeys.OrderBy(p => p.ColumnOrder).Select(p => p.PropertyInfo);
                }
            }

            var dependentProperties = new List<EdmProperty>();

            foreach (var dependentProperty in dependentPropertInfos)
            {
                var property
                    = dependentEnd.GetEntityType()
                                  .GetDeclaredPrimitiveProperty(dependentProperty);

                if (property == null)
                {
                    throw Error.ForeignKeyPropertyNotFound(
                        dependentProperty.Name, dependentEnd.GetEntityType().Name);
                }

                dependentProperties.Add(property);
            }

            var principalEnd = associationType.GetOtherEnd(dependentEnd);

            var associationConstraint
                = new ReferentialConstraint(
                    principalEnd,
                    dependentEnd,
                    principalEnd.GetEntityType().KeyProperties,
                    dependentProperties);

            if (principalEnd.IsRequired())
            {
                associationConstraint.ToProperties.Each(p => p.Nullable = false);
            }

            associationType.Constraint = associationConstraint;
        }
コード例 #37
0
 /// <summary>
 ///     Add the given referential constraint to the collection of referential constraints
 /// </summary>
 internal void AddReferentialConstraint(ReferentialConstraint referentialConstraint)
 {
     ReferentialConstraints.Source.Add(referentialConstraint);
 }
コード例 #38
0
 // <summary>
 // Add the given referential constraint to the collection of referential constraints
 // </summary>
 internal void AddReferentialConstraint(ReferentialConstraint referentialConstraint)
 {
     ReferentialConstraints.Source.Add(referentialConstraint);
 }
コード例 #39
0
        protected virtual void Visit(ReferentialConstraint referentialConstraint)
        {
            foreach (var property in referentialConstraint.FromProperties)
            {
                Visit(property);
            }
            Visit(referentialConstraint.FromRole);

            foreach (var property in referentialConstraint.ToProperties)
            {
                Visit(property);
            }
            Visit(referentialConstraint.ToRole);
        }
コード例 #40
0
        /// <summary>
        ///     Creates an EntityKey for a principal entity based on the foreign key values contained
        ///     in this entity.  This implies that this entity is at the dependent end of the relationship.
        /// </summary>
        /// <param name="dependentEntry"> The EntityEntry for the dependent that contains the FK </param>
        /// <param name="constraint"> The constraint that describes this FK relationship </param>
        /// <param name="principalEntitySet"> The entity set at the principal end of the the relationship </param>
        /// <param name="useOriginalValues"> If true then the key will be constructed from the original FK values </param>
        /// <returns> The key, or null if any value in the key is null </returns>
        public static EntityKey CreateKeyFromForeignKeyValues(
            EntityEntry dependentEntry, ReferentialConstraint constraint, EntitySet principalEntitySet, bool useOriginalValues)
        {
            // Build the key values.  If any part of the key is null, then the entire key
            // is considered null.
            var dependentProps = constraint.ToProperties;
            var numValues = dependentProps.Count;
            if (numValues == 1)
            {
                var keyValue = useOriginalValues
                                   ? dependentEntry.GetOriginalEntityValue(dependentProps.First().Name)
                                   : dependentEntry.GetCurrentEntityValue(dependentProps.First().Name);
                return keyValue == DBNull.Value ? null : new EntityKey(principalEntitySet, keyValue);
            }

            // Note that the properties in the principal entity set may be in a different order than
            // they appear in the constraint.  Therefore, we create name value mappings to ensure that
            // the correct values are associated with the correct properties.
            // Unfortunately, there is not way to call the public EntityKey constructor that takes pairs
            // because the internal "object" constructor hides it.  Even this doesn't work:
            // new EntityKey(principalEntitySet, (IEnumerable<KeyValuePair<string, object>>)keyValues)
            var keyNames = principalEntitySet.ElementType.KeyMemberNames;
            Debug.Assert(keyNames.Length == numValues, "Number of entity set key names does not match constraint names");
            var values = new object[numValues];
            var principalProps = constraint.FromProperties;
            for (var i = 0; i < numValues; i++)
            {
                var value = useOriginalValues
                                ? dependentEntry.GetOriginalEntityValue(dependentProps[i].Name)
                                : dependentEntry.GetCurrentEntityValue(dependentProps[i].Name);
                if (value == DBNull.Value)
                {
                    return null;
                }
                var keyIndex = Array.IndexOf(keyNames, principalProps[i].Name);
                Debug.Assert(keyIndex >= 0 && keyIndex < numValues, "Could not find constraint prop name in entity set key names");
                values[keyIndex] = value;
            }
            return new EntityKey(principalEntitySet, values);
        }
コード例 #41
0
 private static bool IsEntityDependentSideOfBothAssociations(
     EntitySet storeEntitySet,
     ReferentialConstraint constraint0,
     ReferentialConstraint constraint1)
 {
     return ((RefType)constraint0.ToRole.TypeUsage.EdmType).ElementType == storeEntitySet.ElementType
            && ((RefType)constraint1.ToRole.TypeUsage.EdmType).ElementType == storeEntitySet.ElementType;
 }
コード例 #42
0
        /// <summary>
        ///     If this is a property that participates in the principal end of a referential constraint, this method will return
        ///     the corresponding property on the dependent end.
        /// </summary>
        /// <example>
        ///     <ReferentialConstraint>
        ///         <Principal Role="DiscontinuedProduct">
        ///             <PropertyRef Name="ProductId" />
        ///             <PropertyRef Name="ProductName" />
        ///         </Principal>
        ///         <Dependent Role="DiscontinuedItem">
        ///             <PropertyRef Name="ItemId" />
        ///             <PropertyRef Name="ItemName" />
        ///         </Dependent>
        ///     </ReferentialConstraint>
        ///     In this example, if 'ProductName' were passed into this method, 'ItemName' would be returned.
        /// </example>
        /// <param name="property">The property on the principal end of the referential constraint</param>
        /// <param name="refConstraint">The referential constraint.</param>
        /// <returns>The property on the dependent end of the referentail constraint corresponding to the property on the principal end</returns>
        /// <exception cref="ArgumentNullException">if the ref constraint is null</exception>
        /// <exception cref="InvalidOperationException">if the property cannot be found among the properties on the principal end of the referential constraint</exception>
        public static EdmProperty GetDependentProperty(this EdmProperty property, ReferentialConstraint refConstraint)
        {
            if (refConstraint == null)
            {
                throw new ArgumentNullException("refConstraint");
            }

            var indexInFromProperties = refConstraint.FromProperties.IndexOf(property);
            if (indexInFromProperties == -1)
            {
                throw new InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentCulture, Resources.ErrorNoPropertyInRefConstraint, property.Name, refConstraint.FromRole.Name,
                        refConstraint.ToRole.Name));
            }

            return refConstraint.ToProperties.ElementAt(indexInFromProperties);
        }
コード例 #43
0
        /// <summary>
        ///     Creates a read-only AssociationType instance from the specified parameters.
        /// </summary>
        /// <param name="name">The name of the association type.</param>
        /// <param name="namespaceName">The namespace of the association type.</param>
        /// <param name="foreignKey">Flag that indicates a foreign key (FK) relationship.</param>
        /// <param name="dataSpace">The data space for the association type.</param>
        /// <param name="sourceEnd">The source association end member.</param>
        /// <param name="targetEnd">The target association end member.</param>
        /// <param name="constraint">A referential constraint.</param>
        /// <param name="metadataProperties">Metadata properties to be associated with the instance.</param>
        /// <returns>The newly created AssociationType instance.</returns>
        /// <exception cref="System.ArgumentException">The specified name is null or empty.</exception>
        /// <exception cref="System.ArgumentException">The specified namespace is null or empty.</exception>
        public static AssociationType Create(
            string name,
            string namespaceName,
            bool foreignKey,
            DataSpace dataSpace,
            AssociationEndMember sourceEnd,
            AssociationEndMember targetEnd,
            ReferentialConstraint constraint,
            IEnumerable<MetadataProperty> metadataProperties)
        {
            Check.NotEmpty(name, "name");
            Check.NotEmpty(namespaceName, "namespaceName");

            var instance = new AssociationType(name, namespaceName, foreignKey, dataSpace);

            if (sourceEnd != null)
            {
                instance.SourceEnd = sourceEnd;
            }

            if (targetEnd != null)
            {
                instance.TargetEnd = targetEnd;
            }

            if (constraint != null)
            {
                instance.AddReferentialConstraint(constraint);
            }

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

            instance.SetReadOnly();

            return instance;
        }
コード例 #44
0
        public void Create_sets_properties_and_seals_the_instance()
        {
            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 constraint =
                new ReferentialConstraint(
                    sourceEnd,
                    targetEnd,
                    new[] { new EdmProperty("SourceProperty") },
                    new[] { new EdmProperty("TargetProperty") });
            var associationType =
                AssociationType.Create(
                    "AssociationType",
                    "Namespace",
                    true,
                    DataSpace.CSpace,
                    sourceEnd,
                    targetEnd,
                    constraint,
                    Enumerable.Empty<MetadataProperty>());
            var sourceSet = new EntitySet("SourceSet", "Schema", "Table", "Query", source);
            var targetSet = new EntitySet("TargetSet", "Schema", "Table", "Query", target);
            var metadataProperty =
                new MetadataProperty(
                    "MetadataProperty",
                    TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)),
                    "value");
            var associationSet = 
                AssociationSet.Create(
                    "AssociationSet",
                    associationType,
                    sourceSet,
                    targetSet,
                    new[] { metadataProperty });

            Assert.Equal("AssociationSet", associationSet.Name);
            Assert.Same(associationType, associationSet.ElementType);
            Assert.Same(sourceSet, associationSet.SourceSet);
            Assert.Same(targetSet, associationSet.TargetSet);
            Assert.Same(source, associationSet.SourceEnd.GetEntityType());
            Assert.Same(target, associationSet.TargetEnd.GetEntityType());
            Assert.Same(metadataProperty, associationSet.MetadataProperties.SingleOrDefault(p => p.Name == "MetadataProperty"));
            Assert.True(associationSet.IsReadOnly);
        }