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; }
/// <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; }
/// <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; }
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; }
internal RoleBoolean(AssociationSetEnd end) { m_metadataItem = end; }