Beispiel #1
0
 private XElement GenerateReferentialConstrait(ReferentialConstraint rc, XNamespace xmlNamespace)
 {
     return(new XElement(
                xmlNamespace + "ReferentialConstraint",
                this.GenerateDocumentation(xmlNamespace, rc),
                this.GenerateReferentialEnd("Principal", rc.PrincipalAssociationEnd, rc.PrincipalProperties, xmlNamespace),
                this.GenerateReferentialEnd("Dependent", rc.DependentAssociationEnd, rc.DependentProperties, xmlNamespace),
                this.GenerateAnnotations(xmlNamespace, rc)));
 }
 internal static bool TryCreateSourceKey(
     ReferentialConstraint metadata,
     PropagatorResult record,
     bool isInsert,
     out UpdateCommandOrderer.ForeignKeyValue key)
 {
     key = new UpdateCommandOrderer.ForeignKeyValue(metadata, record, false, isInsert);
     return(key.Key != null);
 }
 /// <summary>
 /// Initialize foreign key object for the source of a foreign key.
 /// </summary>
 /// <param name="metadata">Sets Metadata</param>
 /// <param name="record">Record containing key value</param>
 /// <param name="isInsert">Indicates whether the key value is being inserted or deleted</param>
 /// <param name="key">Outputs key object</param>
 /// <returns>true if the record contains key values for this constraint; false otherwise</returns>
 internal static bool TryCreateSourceKey(ReferentialConstraint metadata, PropagatorResult record, bool isInsert, out ForeignKeyValue key)
 {
     key = new ForeignKeyValue(metadata, record, false, isInsert);
     if (null == key.Key)
     {
         return(false);
     }
     return(true);
 }
Beispiel #4
0
            protected override void VisitEdmAssociationConstraint(ReferentialConstraint item)
            {
                Dispatch(item);

                if (item != null)
                {
                    VisitMetadataItem(item);
                }
            }
Beispiel #5
0
 protected override void VisitEdmAssociationConstraint(ReferentialConstraint item)
 {
     this.Dispatch <ReferentialConstraint>(item);
     if (item == null)
     {
         return;
     }
     this.VisitMetadataItem((MetadataItem)item);
 }
        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);
        }
        /// <summary>
        /// Cosntruct RelationshipDetail accoring to ReferentialConstraint.
        /// </summary>
        /// <param name="referentialConstraint">Referential constraint to get foreign keys from.</param>
        internal RelationshipDetail(
            ReferentialConstraint referentialConstraint)
        {
            if (referentialConstraint == null)
            {
                return;
            }

            Initialize(referentialConstraint);
        }
Beispiel #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();
 }
 private static bool ToPropertyHasNonNullableColumn(ReferentialConstraint constraint)
 {
     foreach (EdmProperty property in constraint.ToProperties)
     {
         if (!property.Nullable)
         {
             return(true);
         }
     }
     return(false);
 }
        public virtual string GetForeignKeyConstraintName(ReferentialConstraint constraint)
        {
            var name = constraint.FromRole.DeclaringType.Name;

            if (!name.StartsWith("FK_", StringComparison.InvariantCultureIgnoreCase))
            {
                name = "FK_" + name;
            }

            return(name);
        }
Beispiel #11
0
 protected virtual void VisitEdmAssociationConstraint(ReferentialConstraint item)
 {
     if (item != null)
     {
         VisitMetadataItem(item);
         if (item.ToRole != null)
         {
             VisitEdmAssociationEnd(item.ToRole);
         }
         VisitCollection(item.ToProperties, VisitEdmProperty);
     }
 }
Beispiel #12
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();
 }
        private static SimpleMappingContext CreateSimpleMappingContext(bool isForeignKey)
        {
            var int32TypeUsage = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));
            var storeP1        = new[] { CreateStoreProperty("storeSourceId", "int") };
            var storeP2        = new[] { CreateStoreProperty("storeTargetId", "int") };
            var modelP1        = new[] { EdmProperty.Create("modelSourceId", int32TypeUsage) };
            var modelP2        = new[] { EdmProperty.Create("modelTargetId", int32TypeUsage) };
            var storeET1       = EntityType.Create("storeET1", "N", DataSpace.SSpace, new[] { "storeSourceId" }, storeP1, null);
            var storeET2       = EntityType.Create("storeET2", "N", DataSpace.SSpace, new[] { "storeTargetId" }, storeP2, null);
            var modelET1       = EntityType.Create("modelET1", "N", DataSpace.CSpace, new[] { "modelSourceId" }, modelP1, null);
            var modelET2       = EntityType.Create("modelET2", "N", DataSpace.CSpace, new[] { "modelTargetId" }, modelP2, null);
            var storeES1       = EntitySet.Create("storeES1", null, null, null, storeET1, null);
            var storeES2       = EntitySet.Create("storeES2", null, null, null, storeET2, null);
            var modelES1       = EntitySet.Create("modelES1", null, null, null, modelET1, null);
            var modelES2       = EntitySet.Create("modelES2", null, null, null, modelET2, null);
            var storeEM1       = AssociationEndMember.Create(
                "storeEM1", storeET1.GetReferenceType(), RelationshipMultiplicity.One, OperationAction.None, null);
            var storeEM2 = AssociationEndMember.Create(
                "storeEM2", storeET2.GetReferenceType(), RelationshipMultiplicity.One, OperationAction.None, null);
            var modelEM1 = AssociationEndMember.Create(
                "modelEM1", modelET1.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null);
            var modelEM2 = AssociationEndMember.Create(
                "modelEM2", modelET2.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null);
            var storeRC        = new ReferentialConstraint(storeEM1, storeEM2, storeP1, storeP2);
            var modelRC        = new ReferentialConstraint(modelEM1, modelEM2, modelP1, modelP2);
            var storeAT        = AssociationType.Create("storeAT", "N", isForeignKey, DataSpace.SSpace, storeEM1, storeEM2, storeRC, null);
            var modelAT        = AssociationType.Create("modelAT", "N", isForeignKey, DataSpace.CSpace, modelEM1, modelEM2, modelRC, null);
            var storeAS        = AssociationSet.Create("storeAS", storeAT, storeES1, storeES2, null);
            var modelAS        = AssociationSet.Create("modelAS", modelAT, modelES1, modelES2, null);
            var storeContainer = EntityContainer.Create(
                "storeContainer", DataSpace.SSpace, new EntitySetBase[] { storeES1, storeES2, storeAS }, null, null);
            var modelContainer = EntityContainer.Create(
                "modelContainer", DataSpace.CSpace, new EntitySetBase[] { modelES1, modelES2, modelAS }, null, null);

            var mappingContext = new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true);

            mappingContext.AddMapping(storeP1[0], modelP1[0]);
            mappingContext.AddMapping(storeP2[0], modelP2[0]);
            mappingContext.AddMapping(storeET1, modelET1);
            mappingContext.AddMapping(storeET2, modelET2);
            mappingContext.AddMapping(storeES1, modelES1);
            mappingContext.AddMapping(storeES2, modelES2);
            mappingContext.AddMapping(storeEM1, modelEM1);
            mappingContext.AddMapping(storeEM2, modelEM2);
            mappingContext.AddMapping(storeAT, modelAT);
            mappingContext.AddMapping(storeAS, modelAS);
            mappingContext.AddMapping(storeAS.AssociationSetEnds[0], modelAS.AssociationSetEnds[0]);
            mappingContext.AddMapping(storeAS.AssociationSetEnds[1], modelAS.AssociationSetEnds[1]);
            mappingContext.AddMapping(storeContainer, modelContainer);

            return(mappingContext);
        }
Beispiel #14
0
        private static void InitializeForeignKeyMaps(HashSet<EntityContainer> containers, HashSet<EntitySet> tables, out KeyToListMap<EntitySetBase, ReferentialConstraint> sourceMap, out KeyToListMap<EntitySetBase, ReferentialConstraint> targetMap)
        {
            sourceMap = new KeyToListMap<EntitySetBase, ReferentialConstraint>(EqualityComparer<EntitySetBase>.Default);
            targetMap = new KeyToListMap<EntitySetBase, ReferentialConstraint>(EqualityComparer<EntitySetBase>.Default);

            // Retrieve relationship ends from each container to populate edges in dependency
            // graph
            foreach (EntityContainer container in containers)
            {
                foreach (EntitySetBase extent in container.BaseEntitySets)
                {
                    AssociationSet associationSet = extent as AssociationSet;

                    if (null != associationSet)
                    {
                        AssociationSetEnd source = null;
                        AssociationSetEnd target = null;

                        var ends = associationSet.AssociationSetEnds;

                        if (2 == ends.Count)
                        {
                            // source is equivalent to the "to" end of relationship, target is "from"
                            AssociationType associationType = associationSet.ElementType;
                            bool constraintFound = false;
                            ReferentialConstraint fkConstraint = null;
                            foreach (ReferentialConstraint constraint in associationType.ReferentialConstraints)
                            {
                                if (constraintFound) { Debug.Fail("relationship set should have at most one constraint"); }
                                else { constraintFound = true; }
                                source = associationSet.AssociationSetEnds[constraint.ToRole.Name];
                                target = associationSet.AssociationSetEnds[constraint.FromRole.Name];
                                fkConstraint = constraint;
                            }

                            Debug.Assert(constraintFound && null != target && null != source, "relationship set must have at least one constraint");
                            // only understand binary (foreign key) relationships between entity sets
                            if (null != target && null != source)
                            {
                                if (tables.Contains(target.EntitySet)&&
                                    tables.Contains(source.EntitySet))
                                {
                                    // Remember metadata
                                    sourceMap.Add(source.EntitySet, fkConstraint);
                                    targetMap.Add(target.EntitySet, fkConstraint);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #15
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);
        }
 internal static AssociationIdentity CreateAssociationIdentity(ReferentialConstraint rc)
 {
     if (rc == null)
     {
         Debug.Fail("You passed a null Referential Constraint to CreateAssociationIdentity!");
     }
     else
     {
         var id = new AssociationIdentityForReferentialConstraint(rc);
         return(id);
     }
     return(null);
 }
Beispiel #17
0
 protected virtual void Visit(ReferentialConstraint referentialConstraint)
 {
     foreach (EdmProperty edmProperty in this.GetSequence <EdmProperty>((IEnumerable <EdmProperty>)referentialConstraint.FromProperties, (Func <EdmProperty, string>)(it => it.Identity)))
     {
         this.Visit(edmProperty);
     }
     this.Visit(referentialConstraint.FromRole);
     foreach (EdmProperty edmProperty in this.GetSequence <EdmProperty>((IEnumerable <EdmProperty>)referentialConstraint.ToProperties, (Func <EdmProperty, string>)(it => it.Identity)))
     {
         this.Visit(edmProperty);
     }
     this.Visit(referentialConstraint.ToRole);
 }
        internal static ReferentialConstraint GetReferentialConstraint(AssociationSet set)
        {
            // this seeems like a hack, but it is what we have right now.
            ReferentialConstraint constraint = null;

            foreach (ReferentialConstraint rc in set.ElementType.ReferentialConstraints)
            {
                Debug.Assert(constraint == null, "we should only get one");
                constraint = rc;
            }
            Debug.Assert(constraint != null, "we should get at least one constraint");
            return(constraint);
        }
        protected override void Visit(ReferentialConstraint referentialConstraint)
        {
            int instanceIndex;

            if (!this.AddObjectToSeenListAndHashBuilder((object)referentialConstraint, out instanceIndex))
            {
                return;
            }
            this.AddObjectStartDumpToHashBuilder((object)referentialConstraint, instanceIndex);
            this.AddObjectContentToHashBuilder((object)referentialConstraint.Identity);
            base.Visit(referentialConstraint);
            this.AddObjectEndDumpToHashBuilder();
        }
Beispiel #20
0
 protected virtual void VisitEdmAssociationConstraint(ReferentialConstraint item)
 {
     if (item == null)
     {
         return;
     }
     this.VisitMetadataItem((MetadataItem)item);
     if (item.ToRole != null)
     {
         this.VisitEdmAssociationEnd(item.ToRole);
     }
     EdmModelVisitor.VisitCollection <EdmProperty>((IEnumerable <EdmProperty>)item.ToProperties, new Action <EdmProperty>(this.VisitEdmProperty));
 }
        private bool CheckIfConstraintMappedToForeignKeyAssociation(
            QueryRewriter childRewriter,
            QueryRewriter parentRewriter,
            Set <Cell> cells)
        {
            ViewgenContext            viewgenContext1 = childRewriter.ViewgenContext;
            ViewgenContext            viewgenContext2 = parentRewriter.ViewgenContext;
            List <Set <EdmProperty> > source1         = new List <Set <EdmProperty> >();
            List <Set <EdmProperty> > source2         = new List <Set <EdmProperty> >();

            foreach (Cell cell in cells)
            {
                if (cell.CQuery.Extent.BuiltInTypeKind != BuiltInTypeKind.AssociationSet)
                {
                    Set <EdmProperty> cslotsForTableColumns1 = cell.GetCSlotsForTableColumns(this.ChildColumns);
                    if (cslotsForTableColumns1 != null && cslotsForTableColumns1.Count != 0)
                    {
                        source1.Add(cslotsForTableColumns1);
                    }
                    Set <EdmProperty> cslotsForTableColumns2 = cell.GetCSlotsForTableColumns(this.ParentColumns);
                    if (cslotsForTableColumns2 != null && cslotsForTableColumns2.Count != 0)
                    {
                        source2.Add(cslotsForTableColumns2);
                    }
                }
            }
            if (source1.Count != 0 && source2.Count != 0)
            {
                foreach (AssociationType associationType in viewgenContext1.EntityContainerMapping.EdmEntityContainer.BaseEntitySets.OfType <AssociationSet>().Where <AssociationSet>((Func <AssociationSet, bool>)(it => it.ElementType.IsForeignKey)).Select <AssociationSet, AssociationType>((Func <AssociationSet, AssociationType>)(it => it.ElementType)))
                {
                    ReferentialConstraint            refConstraint = associationType.ReferentialConstraints.FirstOrDefault <ReferentialConstraint>();
                    IEnumerable <Set <EdmProperty> > source3       = source1.Where <Set <EdmProperty> >((Func <Set <EdmProperty>, bool>)(it => it.SetEquals(new Set <EdmProperty>((IEnumerable <EdmProperty>)refConstraint.ToProperties))));
                    IEnumerable <Set <EdmProperty> > source4       = source2.Where <Set <EdmProperty> >((Func <Set <EdmProperty>, bool>)(it => it.SetEquals(new Set <EdmProperty>((IEnumerable <EdmProperty>)refConstraint.FromProperties))));
                    if (source3.Count <Set <EdmProperty> >() != 0 && source4.Count <Set <EdmProperty> >() != 0)
                    {
                        foreach (IEnumerable <EdmProperty> properties1_1 in source4)
                        {
                            Set <int> propertyIndexes = ForeignConstraint.GetPropertyIndexes(properties1_1, refConstraint.FromProperties);
                            foreach (IEnumerable <EdmProperty> properties1_2 in source3)
                            {
                                if (ForeignConstraint.GetPropertyIndexes(properties1_2, refConstraint.ToProperties).SequenceEqual <int>((IEnumerable <int>)propertyIndexes))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
Beispiel #22
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);
        }
Beispiel #23
0
        protected virtual void Visit(ReferentialConstraint referentialConstraint)
        {
            foreach (var property in GetSequence(referentialConstraint.FromProperties, it => it.Identity))
            {
                Visit(property);
            }
            Visit(referentialConstraint.FromRole);

            foreach (var property in GetSequence(referentialConstraint.ToProperties, it => it.Identity))
            {
                Visit(property);
            }
            Visit(referentialConstraint.ToRole);
        }
        private void ResolveReferentialConstraint(AssociationType association, ReferentialConstraint constraint)
        {
            constraint.DependentAssociationEnd = this.ResolveAssociationEndReference(association, constraint.DependentAssociationEnd);
            if (constraint.DependentAssociationEnd != null)
            {
                this.ResolvePropertyReferences(constraint.DependentAssociationEnd.EntityType, constraint.DependentProperties);
            }

            constraint.PrincipalAssociationEnd = this.ResolveAssociationEndReference(association, constraint.PrincipalAssociationEnd);
            if (constraint.PrincipalAssociationEnd != null)
            {
                this.ResolvePropertyReferences(constraint.PrincipalAssociationEnd.EntityType, constraint.PrincipalProperties);
            }
        }
Beispiel #25
0
        public virtual void Apply(AssociationType item, DbModel model)
        {
            Check.NotNull <AssociationType>(item, nameof(item));
            Check.NotNull <DbModel>(model, nameof(model));
            AssociationEndMember principalEnd;
            AssociationEndMember dependentEnd;

            if (item.Constraint != null || item.IsIndependent() || item.IsOneToOne() && item.IsSelfReferencing() || !item.TryGuessPrincipalAndDependentEnds(out principalEnd, out dependentEnd))
            {
                return;
            }
            IEnumerable <EdmProperty> source1 = principalEnd.GetEntityType().KeyProperties();

            if (!source1.Any <EdmProperty>() || !this.SupportsMultipleAssociations && model.ConceptualModel.GetAssociationTypesBetween(principalEnd.GetEntityType(), dependentEnd.GetEntityType()).Count <AssociationType>() > 1)
            {
                return;
            }
            IEnumerable <EdmProperty> source2 = source1.SelectMany((Func <EdmProperty, IEnumerable <EdmProperty> >)(p => (IEnumerable <EdmProperty>)dependentEnd.GetEntityType().DeclaredProperties), (p, d) => new
            {
                p = p,
                d = d
            }).Where(_param1 =>
            {
                if (this.MatchDependentKeyProperty(item, dependentEnd, _param1.d, principalEnd.GetEntityType(), _param1.p))
                {
                    return(_param1.p.UnderlyingPrimitiveType == _param1.d.UnderlyingPrimitiveType);
                }
                return(false);
            }).Select(_param0 => _param0.d);

            if (!source2.Any <EdmProperty>() || source2.Count <EdmProperty>() != source1.Count <EdmProperty>())
            {
                return;
            }
            IEnumerable <EdmProperty> source3 = dependentEnd.GetEntityType().KeyProperties();
            bool flag = source3.Count <EdmProperty>() == source2.Count <EdmProperty>() && source3.All <EdmProperty>(new Func <EdmProperty, bool>(((Enumerable)source2).Contains <EdmProperty>));

            if ((dependentEnd.IsMany() || item.IsSelfReferencing()) && flag || !dependentEnd.IsMany() && !flag)
            {
                return;
            }
            ReferentialConstraint referentialConstraint = new ReferentialConstraint((RelationshipEndMember)principalEnd, (RelationshipEndMember)dependentEnd, (IEnumerable <EdmProperty>)source1.ToList <EdmProperty>(), (IEnumerable <EdmProperty>)source2.ToList <EdmProperty>());

            item.Constraint = referentialConstraint;
            if (!principalEnd.IsRequired())
            {
                return;
            }
            referentialConstraint.ToProperties.Each <EdmProperty, bool>((Func <EdmProperty, bool>)(p => p.Nullable = false));
        }
Beispiel #26
0
        private ReferentialConstraint ParseReferentialConstraint(XElement constraintElement)
        {
            var constraint       = new ReferentialConstraint();
            var principalElement = constraintElement.Elements().Single(el => this.IsXsdlElement(el, "Principal"));
            var dependentElement = constraintElement.Elements().Single(el => this.IsXsdlElement(el, "Dependent"));

            constraint.PrincipalAssociationEnd = new AssociationEndReference(principalElement.GetRequiredAttributeValue("Role"));
            constraint.DependentAssociationEnd = new AssociationEndReference(dependentElement.GetRequiredAttributeValue("Role"));

            this.ParseConstraintProperties(constraint.PrincipalProperties, principalElement);
            this.ParseConstraintProperties(constraint.DependentProperties, dependentElement);

            this.ParseAnnotations(constraint, constraintElement);
            return(constraint);
        }
        /// <summary>
        /// Initialize foreign key details according to referential constraint.
        /// </summary>
        /// <param name="referentialConstraint">Referential constraint to get foreign keys from.</param>
        private void Initialize(
            ReferentialConstraint referentialConstraint)
        {
            if (referentialConstraint == null)
            {
                return;
            }

            if (referentialConstraint.FromRole != null &&
                referentialConstraint.FromProperties != null &&
                referentialConstraint.FromProperties.Count > 0)
            {
                RefType fromType =
                    referentialConstraint.FromRole.TypeUsage.EdmType as RefType;

                if (fromType != null)
                {
                    FromDetails = new ForeignKeyDetail()
                    {
                        ContainerClass = fromType.ElementType.Name,
                        Keys           =
                            referentialConstraint.FromProperties.Select(m => m.Name).ToList(),
                        RelationshipMultiplicity =
                            referentialConstraint.FromRole.RelationshipMultiplicity
                    };
                }
            }

            if (referentialConstraint.ToRole != null &&
                referentialConstraint.ToProperties != null &&
                referentialConstraint.ToProperties.Count > 0)
            {
                RefType toType =
                    referentialConstraint.ToRole.TypeUsage.EdmType as RefType;

                if (toType != null)
                {
                    ToDetails = new ForeignKeyDetail()
                    {
                        ContainerClass = toType.ElementType.Name,
                        Keys           =
                            referentialConstraint.ToProperties.Select(m => m.Name).ToList(),
                        RelationshipMultiplicity =
                            referentialConstraint.ToRole.RelationshipMultiplicity
                    };
                }
            }
        }
Beispiel #28
0
        private void FixRelationshipColumnOrder(ReferentialConstraint referentialConstraint, ref List <ColumnDefinition> columns, ref List <ColumnDefinition> primaryKeyColumns)
        {
            string sql = "SELECT C.name AS ColumnName, RC.name AS ReferencedColumnName"
                         + " FROM sys.foreign_keys FK"
                         + " JOIN sys.foreign_key_columns FKC ON FK.object_id = FKC.constraint_object_id"
                         + " JOIN sys.columns C ON FKC.parent_object_id = C.object_id AND FKC.parent_column_id = C.column_id"
                         + " JOIN sys.columns RC ON FKC.referenced_object_id = RC.object_id AND FKC.referenced_column_id = RC.column_id"
                         + $" WHERE FK.schema_id = SCHEMA_ID('{referentialConstraint.ConstraintSchema}') AND FK.name = '{referentialConstraint.ConstraintName}'"
                         + " ORDER BY FKC.constraint_column_id;";

            var dataRows = SqlUtil.GetDataRows(_connectionString, sql);

            columns = columns.OrderBy(_ => dataRows.Select(dr => dr["ColumnName"]).ToList().IndexOf(_.ColumnName)).ToList();

            primaryKeyColumns = primaryKeyColumns.OrderBy(_ => dataRows.Select(dr => dr["ReferencedColumnName"]).ToList().IndexOf(_.ColumnName)).ToList();
        }
        /// <summary>
        /// True if the specified association end is the principal end in an identifying relationship.
        /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key.
        /// </summary>
        public bool IsPrincipalEndOfIdentifyingRelationship(AssociationEndMember associationEnd)
        {
            if (associationEnd == null)
            {
                throw new ArgumentNullException("associationEnd");
            }

            ReferentialConstraint refConstraint = ((AssociationType)associationEnd.DeclaringType).ReferentialConstraints.Where(rc => rc.FromRole == associationEnd).SingleOrDefault();

            if (refConstraint != null)
            {
                EntityType entity = refConstraint.ToRole.GetEntityType();
                return(!refConstraint.ToProperties.Where(tp => !entity.KeyMembers.Contains(tp)).Any());
            }
            return(false);
        }
Beispiel #30
0
        /// <summary>
        /// Takes key values from the given principal key and transfers them to the foreign key properties
        /// of the dependant entry.  This method requires a context, but does not require that either
        /// entity or key is in the context.  This allows it to work in NoTracking cases where we have the context
        /// but we're not tracked by that context.
        /// </summary>
        /// <param name="dependentEntity">The entity into which foreign key values will be written</param>
        /// <param name="principalEntity">The key from which key values will be obtained</param>
        internal void UpdateForeignKeyValues(IEntityWrapper dependentEntity, EntityKey principalKey)
        {
            Debug.Assert(dependentEntity.Entity != null, "dependentEntity.Entity == null");
            Debug.Assert(principalKey != null, "principalKey == null");
            Debug.Assert(!principalKey.IsTemporary, "Cannot update from a temp key");
            Debug.Assert(this.IsForeignKey, "cannot update foreign key values if the relationship is not a FK");
            ReferentialConstraint constraint = ((AssociationType)this.RelationMetadata).ReferentialConstraints[0];

            Debug.Assert(constraint != null, "null constraint");

            ObjectStateManager stateManager = ObjectContext.ObjectStateManager;

            stateManager.TransactionManager.BeginForeignKeyUpdate(this);
            try
            {
                EntitySet dependentEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[FromEndProperty.Name].EntitySet;
                StateManagerTypeMetadata dependentTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, dependentEntitySet);

                for (int i = 0; i < constraint.FromProperties.Count; i++)
                {
                    object value            = principalKey.FindValueByName(constraint.FromProperties[i].Name);
                    int    dependentOrdinal = dependentTypeMetadata.GetOrdinalforOLayerMemberName(constraint.ToProperties[i].Name);
                    object currentValue     = dependentTypeMetadata.Member(dependentOrdinal).GetValue(dependentEntity.Entity);
                    if (!ByValueEqualityComparer.Default.Equals(currentValue, value))
                    {
                        dependentEntity.SetCurrentValue(
                            dependentEntity.ObjectStateEntry,
                            dependentTypeMetadata.Member(dependentOrdinal),
                            -1,
                            dependentEntity.Entity,
                            value);
                    }
                }

                SetCachedForeignKey(principalKey, dependentEntity.ObjectStateEntry);
                if (WrappedOwner.ObjectStateEntry != null)
                {
                    stateManager.ForgetEntryWithConceptualNull(WrappedOwner.ObjectStateEntry, resetAllKeys: false);
                }
            }
            finally
            {
                stateManager.TransactionManager.EndForeignKeyUpdate();
            }
        }
 // <summary>
 // Constructs an EntityContainerAssociationSetEnd
 // </summary>
 // <param name="parentElement"> Reference to the schema element. </param>
 public ReferentialConstraintRoleElement(ReferentialConstraint parentElement)
     : base(parentElement)
 {
 }
        private static AssociationType ConvertToAssociationType(
            Som.Relationship element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            Debug.Assert(element.RelationshipKind == RelationshipKind.Association);

            var associationType = new AssociationType(
                element.Name,
                element.Namespace,
                element.IsForeignKey,
                GetDataSpace(providerManifest));
            newGlobalItems.Add(element, associationType);

            foreach (Som.RelationshipEnd end in element.Ends)
            {
                Som.SchemaType entityTypeElement = end.Type;
                var endEntityType = (EntityType)LoadSchemaElement(
                    entityTypeElement,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);

                var endMember = InitializeAssociationEndMember(associationType, end, endEntityType);
                AddOtherContent(end, endMember);
                // Loop through and convert the operations
                foreach (var operation in end.Operations)
                {
                    // Process only the ones that we recognize
                    if (operation.Operation
                        != Som.Operation.Delete)
                    {
                        continue;
                    }

                    // Determine the action for this operation
                    var action = OperationAction.None;
                    switch (operation.Action)
                    {
                        case Som.Action.Cascade:
                            action = OperationAction.Cascade;
                            break;
                        case Som.Action.None:
                            action = OperationAction.None;
                            break;
                        default:
                            Debug.Fail("Operation action not supported.");
                            break;
                    }
                    endMember.DeleteBehavior = action;
                }

                // Extract optional Documentation from the end element
                if (end.Documentation != null)
                {
                    endMember.Documentation = ConvertToDocumentation(end.Documentation);
                }
            }

            Debug.Assert(associationType.ReferentialConstraints.Count == 0, "This must never have been initialized");

            for (var i = 0; i < element.Constraints.Count; i++)
            {
                var constraint = element.Constraints[i];
                var fromMember = (AssociationEndMember)associationType.Members[constraint.PrincipalRole.Name];
                var toMember = (AssociationEndMember)associationType.Members[constraint.DependentRole.Name];
                var fromEntityType = ((RefType)fromMember.TypeUsage.EdmType).ElementType;
                var toEntityType = ((RefType)toMember.TypeUsage.EdmType).ElementType;

                var referentialConstraint = new ReferentialConstraint(
                    fromMember, toMember,
                    GetProperties(fromEntityType, constraint.PrincipalRole.RoleProperties),
                    GetProperties(toEntityType, constraint.DependentRole.RoleProperties));

                // Attach the optional Documentation
                if (constraint.Documentation != null)
                {
                    referentialConstraint.Documentation = ConvertToDocumentation(constraint.Documentation);
                }
                if (constraint.PrincipalRole.Documentation != null)
                {
                    referentialConstraint.FromRole.Documentation = ConvertToDocumentation(constraint.PrincipalRole.Documentation);
                }
                if (constraint.DependentRole.Documentation != null)
                {
                    referentialConstraint.ToRole.Documentation = ConvertToDocumentation(constraint.DependentRole.Documentation);
                }

                associationType.AddReferentialConstraint(referentialConstraint);
                AddOtherContent(element.Constraints[i], referentialConstraint);
            }

            // Extract the optional Documentation
            if (element.Documentation != null)
            {
                associationType.Documentation = ConvertToDocumentation(element.Documentation);
            }
            AddOtherContent(element, associationType);

            return associationType;
        }
        /// <summary>
        ///     handle the constraint element
        /// </summary>
        /// <param name="reader"> XmlReader positioned at the constraint element </param>
        private void HandleConstraintElement(XmlReader reader)
        {
            DebugCheck.NotNull(reader);

            var constraint = new ReferentialConstraint(this);
            constraint.Parse(reader);
            Constraints.Add(constraint);

            if (Schema.DataModel == SchemaDataModelOption.EntityDataModel
                && Schema.SchemaVersion >= XmlConstants.EdmVersionForV2)
            {
                // in V2, referential constraint implies foreign key
                _isForeignKey = true;
            }
        }
Beispiel #34
0
        /// <summary>
        /// handle the constraint element
        /// </summary>
        /// <param name="reader">XmlReader positioned at the constraint element</param>
        private void HandleConstraintElement(XmlReader reader)
        {
            Debug.Assert(reader != null);

            ReferentialConstraint constraint = new ReferentialConstraint(this);
            constraint.Parse(reader);
            this.Constraints.Add(constraint);

            if (this.Schema.DataModel == SchemaDataModelOption.EntityDataModel && this.Schema.SchemaVersion >= XmlConstants.EdmVersionForV2)
            {
                // in V2, referential constraint implies foreign key
                _isForeignKey = true;
            }
        }
        /// <summary>
        /// Populate the ResourceReferentialConstraint instance from the ReferentialConstraint instance.
        /// </summary>
        /// <param name="resourceAssociationType">ResourceAssociationType instance.</param>
        /// <param name="referentialConstraint">ReferentialConstraint instance.</param>
        private static void PopulateReferentialConstraint(ResourceAssociationType resourceAssociationType, ReferentialConstraint referentialConstraint)
        {
            ResourceAssociationTypeEnd principalEnd = resourceAssociationType.GetEnd(referentialConstraint.FromRole.Name);
            ResourceAssociationTypeEnd dependentEnd = resourceAssociationType.GetEnd(referentialConstraint.ToRole.Name);

            List<ResourceProperty> dependentProperties = new List<ResourceProperty>();
            foreach (EdmProperty edmProperty in referentialConstraint.ToProperties)
            {
                dependentProperties.Add(dependentEnd.ResourceType.TryResolvePropertyName(edmProperty.Name));
            }

            resourceAssociationType.ReferentialConstraint = new ResourceReferentialConstraint(principalEnd, dependentProperties);
            ObjectContextServiceProvider.PopulateAnnotations(referentialConstraint.MetadataProperties, resourceAssociationType.ReferentialConstraint.AddCustomAnnotation);
        }