internal static EntityDataSourceReferenceGroup Create(Type entityType, AssociationSetEnd end)
        {
            EntityDataSourceUtil.CheckArgumentNull(entityType, "entityType");

            Type groupType = typeof(EntityDataSourceReferenceGroup<>).MakeGenericType(entityType);
            return (EntityDataSourceReferenceGroup)Activator.CreateInstance(groupType, new object[] { end });
        }
            private void GetFromAssociationSetEnd(AssociationSet definingSet, AssociationSet multiplicitySet, out AssociationSetEnd associationSetEnd, out RelationshipMultiplicity multiplicity, out OperationAction deleteBehavior)
            {
                // for a situation like this (CD is CascadeDelete)
                // 
                // --------  CD   --------  CD   --------
                // | A    |1 <-  1| AtoB |* <-  1|  B   |  
                // |      |-------|      |-------|      | 
                // |      |       |      |       |      |
                // --------       --------       --------
                // 
                // You get
                // --------  CD   --------
                // |  A   |* <-  1|  B   |
                // |      |-------|      |
                // |      |       |      |
                // --------       --------
                // 
                // Notice that the of the new "link table association" muliplicities are opposite of what comming into the original link table
                // this seems counter intuitive at first, but makes sense when you think all the way through it
                //
                // CascadeDelete Behavior (we can assume the runtime will always delete cascade 
                //                         to the link table from the outside tables (it actually doesn't, but that is a 















                associationSetEnd = GetAssociationSetEnd(definingSet, true);
                AssociationSetEnd multiplicityAssociationSetEnd = GetAssociationSetEnd(multiplicitySet, false);
                multiplicity = multiplicityAssociationSetEnd.CorrespondingAssociationEndMember.RelationshipMultiplicity;
                deleteBehavior = OperationAction.None;
                if (multiplicity != RelationshipMultiplicity.Many)
                {
                    OperationAction otherEndBehavior = GetAssociationSetEnd(definingSet, false).CorrespondingAssociationEndMember.DeleteBehavior;
                    if(otherEndBehavior == OperationAction.None)
                    {
                        // Since the other end does not have an operation
                        // that means that only one end could possibly have an operation, that is good
                        // so set it the operation
                        deleteBehavior = multiplicityAssociationSetEnd.CorrespondingAssociationEndMember.DeleteBehavior;
                    }
                }
            }
        private static DbRelatedEntityRef RelatedEntityRefFromAssociationSetEnd(EntityType constructedEntityType, DbNewInstanceExpression entityConstructor, AssociationSetEnd principalSetEnd, ReferentialConstraint fkConstraint)
        {
            EntityType 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.
            //
            DbRefExpression principalRef = principalSetEnd.EntitySet.CreateRef(principalEntityType, principalKeyValues);
            DbRelatedEntityRef result = DbExpressionBuilder.CreateRelatedEntityRef(fkConstraint.ToRole, fkConstraint.FromRole, principalRef);

            return result;
        }
示例#4
0
 /// <summary>
 /// Adds the given end to the collection of ends
 /// </summary>
 /// <param name="associationSetEnd"></param>
 internal void AddAssociationSetEnd(AssociationSetEnd associationSetEnd)
 {
     this.AssociationSetEnds.Source.Add(associationSetEnd);
 }
 private AssociationSetEnd CreateModelAssociationSetEnd(LoadMethodSessionState session, AssociationSetEnd storeEnd, AssociationSet parentModelAssociationSet)
 {
     AssociationEndMember associationEnd = session.MappingLookups.StoreAssociationEndMemberToModelAssociationEndMember[storeEnd.CorrespondingAssociationEndMember];
     EntitySet entitySet = session.MappingLookups.StoreEntitySetToModelEntitySet[storeEnd.EntitySet];
     string role = associationEnd.Name;
     AssociationSetEnd end = new AssociationSetEnd(entitySet, parentModelAssociationSet, associationEnd);
     return end;
 }
        private AssociationSet CreateModelAssociationSet(LoadMethodSessionState session, OneToOneMappingSerializer.CollapsedEntityAssociationSet collapsedAssociationSet)
        {
            // create the association
            string associationName = CreateModelName(collapsedAssociationSet.EntitySet.Name, session.UsedGlobalModelTypeNames);
            AssociationType association = new AssociationType(associationName,
                _namespaceName, false, DataSpace.CSpace);

            // create the association set
            string associationSetName = CreateModelName(collapsedAssociationSet.EntitySet.Name, session.UsedEntityContainerItemNames);
            AssociationSet set = new AssociationSet(associationSetName, association);
            
            // create the association and association set end members
            UniqueIdentifierService usedEndMemberNames = new UniqueIdentifierService(false);
            for(int i = 0; i < collapsedAssociationSet.AssociationSets.Count; i++)
            {
                AssociationSetEnd storeEnd;
                RelationshipMultiplicity multiplicity;
                OperationAction deleteBehavior;
                collapsedAssociationSet.GetStoreAssociationSetEnd(i, out storeEnd, out multiplicity, out deleteBehavior);
                AssociationEndMember end = CreateAssociationEndMember(session, storeEnd.CorrespondingAssociationEndMember, usedEndMemberNames, multiplicity, deleteBehavior);
                association.AddMember(end);

                EntitySet entitySet = session.MappingLookups.StoreEntitySetToModelEntitySet[storeEnd.EntitySet];
                AssociationSetEnd setEnd = new AssociationSetEnd(entitySet, set, end);
                set.AddAssociationSetEnd(setEnd);
                session.MappingLookups.StoreAssociationSetEndToModelAssociationSetEnd.Add(storeEnd, setEnd);
            }

            // don't need a referential constraint

            CreateModelNavigationProperties(session, association);

            collapsedAssociationSet.ModelAssociationSet = set;
           
            return set;
        }
示例#7
0
        /// <summary>
        /// Converts an association set from SOM to metadata
        /// </summary>
        /// <param name="relationshipSet">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <param name="container"></param>
        /// <returns>The association set object resulting from the convert</returns>
        private static AssociationSet ConvertToAssociationSet(Som.EntityContainerRelationshipSet relationshipSet,
                                                              DbProviderManifest providerManifest,
                                                              ConversionCache convertedItemCache,
                                                              EntityContainer container,
                                                              Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            Debug.Assert(relationshipSet.Relationship.RelationshipKind == RelationshipKind.Association);

            AssociationType associationType = (AssociationType)LoadSchemaElement((Som.SchemaType)relationshipSet.Relationship,
                                                                                  providerManifest,
                                                                                  convertedItemCache,
                                                                                  newGlobalItems);

            AssociationSet associationSet = new AssociationSet(relationshipSet.Name, associationType);

            foreach (Som.EntityContainerRelationshipSetEnd end in relationshipSet.Ends)
            {
                //-- need the EntityType for the end
                EntityType endEntityType = (EntityType)LoadSchemaElement(end.EntitySet.EntityType,
                                                                         providerManifest,
                                                                         convertedItemCache,
                                                                         newGlobalItems);
                //-- need to get the end member
                AssociationEndMember endMember = (AssociationEndMember)associationType.Members[end.Name];
                //-- create the end
                AssociationSetEnd associationSetEnd = new AssociationSetEnd(GetEntitySet(end.EntitySet, container),
                                                                            associationSet,
                                                                            endMember);

                AddOtherContent(end, associationSetEnd);
                associationSet.AddAssociationSetEnd(associationSetEnd);

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

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

            return associationSet;
        }
 public void GetStoreAssociationSetEnd(int index, out AssociationSetEnd storeAssociationSetEnd, out RelationshipMultiplicity multiplicity, out OperationAction deleteBehavior)
 {
     Debug.Assert(index >= 0 && index < AssociationSets.Count, "out of bounds dude!!");
     Debug.Assert(AssociationSets.Count == 2, "This code depends on only having exactly two AssociationSets");
     GetFromAssociationSetEnd(AssociationSets[index], AssociationSets[(index+1)%2], out storeAssociationSetEnd, out multiplicity, out deleteBehavior);
 }
        private static EdmProperty GetAssociatedFkColumn(AssociationSetEnd store, EdmProperty storeKeyProperty)
        {
            ReferentialConstraint constraint = GetReferentialConstraint(store.ParentAssociationSet);
            if (store.Name == constraint.FromRole.Name)
            {
                for (int i = 0; i < constraint.FromProperties.Count; i++)
                {
                    if (constraint.FromProperties[i] == storeKeyProperty)
                    {
                        // return the matching Fk column
                        return constraint.ToProperties[i];
                    }
                }
            }

                return storeKeyProperty;
        }
 private void WriteEndPropertyElement(XmlWriter writer, AssociationSetEnd store, AssociationSetEnd model)
 {
     writer.WriteStartElement(StorageMslConstructs.EndPropertyMappingElement, _xmlNamespace);
     writer.WriteAttributeString(StorageMslConstructs.EndPropertyMappingNameAttribute, model.Name);
     foreach (EdmProperty storeKeyMember in store.EntitySet.ElementType.KeyMembers)
     {
         EdmProperty modelKeyMember = _lookups.StoreEdmPropertyToModelEdmProperty[storeKeyMember];
         EdmProperty storeFkTableMember = GetAssociatedFkColumn(store, storeKeyMember);
         WriteScalarPropertyElement(writer, storeFkTableMember, modelKeyMember);
     }
     writer.WriteEndElement();
 }
        protected EntityDataSourceReferenceGroup(AssociationSetEnd end)
        {
            EntityDataSourceUtil.CheckArgumentNull(end, "end");

            this.end = end;
        }
 /// <summary>
 /// Adds the given end to the collection of ends
 /// </summary>
 /// <param name="associationSetEnd"></param>
 internal void AddAssociationSetEnd(AssociationSetEnd associationSetEnd)
 {
     this.AssociationSetEnds.Source.Add(associationSetEnd);
 }
        protected override void Visit(AssociationSetEnd associationSetEnd)
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(associationSetEnd, out index))
            {
                return;
            }

            this.AddObjectStartDumpToHashBuilder(associationSetEnd, index);

            #region Inner data visit
            this.AddObjectContentToHashBuilder(associationSetEnd.Identity);
            // Name is covered by Identity

            base.Visit(associationSetEnd);

            #endregion

            this.AddObjectEndDumpToHashBuilder();
        }
 protected virtual void Visit(AssociationSetEnd associationSetEnd)
 {
     Visit(associationSetEnd.CorrespondingAssociationEndMember);
     Visit(associationSetEnd.EntitySet);
     Visit(associationSetEnd.ParentAssociationSet);
 }
        private AssociationSet CreateAssociationSet(LoadMethodSessionState session, 
            AssociationType type)
        {
            AssociationSet set = new AssociationSet(type.Name, type);

            foreach(AssociationEndMember end in type.RelationshipEndMembers)
            {
                EntitySet entitySet = session.GetEntitySet(end);
                DbObjectKey key = session.GetKey(entitySet.ElementType);
                AssociationSetEnd setEnd = new AssociationSetEnd(entitySet, set, end);
                set.AddAssociationSetEnd(setEnd);
            }

            set.SetReadOnly();
            return set;
        }
示例#16
0
 internal RoleBoolean(AssociationSetEnd end)
 {
     m_metadataItem = end;
 }