src/Misc/EFTools/EntityDesignModel/Commands/UpdateConceptualAndMappingModelsCommand.cs
/// <summary>
///     Clone the Association with its ReferentialConstraint (if available), AssociationSet
///     and AssociationSetMapping. If the ReferentialConstraint is available in the temp artifact
///     but we cannot find matching properties in the existing artifact then the whole Association
///     (and AssociationSet and AssociationSetMapping) will not be cloned, a warning message will
///     be issued but otherwise the process is not stopped.
///     But if the Association cannot be created for any other reason that's an error and an
///     UpdateModelFromDatabaseException will be thrown.
/// </summary>
/// <param name="cpc">CommandProcessorContext for the commands to be issued</param>
/// <param name="existingArtifact">the existing artifact in which to make these changes</param>
/// <param name="assocInTempArtifact">the Association in the temp artifact to be cloned</param>
/// <param name="end1InTempArtifact">the end of the Association in the temp artifact to be cloned to be treated as End1</param>
/// <param name="end2InTempArtifact">the end of the Association in the temp artifact to be cloned to be treated as End2</param>
/// <param name="navProp1InTempArtifact">the NavigationProperty for End1 in the temp artifact to be cloned</param>
/// <param name="navProp2InTempArtifact">the NavigationProperty for End2 in the temp artifact to be cloned</param>
/// <param name="end1EntityTypeInExistingArtifact">the EntityType in the existing artifact matching the End1 target in the temp artifact</param>
/// <param name="end2EntityTypeInExistingArtifact">the EntityType in the existing artifact matching the End2 target in the temp artifact</param>
/// <param name="tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact">
///     a Dictionary mapping temp artifact EntityTypes which have
///     been identified as new to their equivalent in the existing artifact
/// </param>
Clone the Association with its ReferentialConstraint (if available), AssociationSet
and AssociationSetMapping. If the ReferentialConstraint is available in the temp artifact
but we cannot find matching properties in the existing artifact then the whole Association
(and AssociationSet and AssociationSetMapping) will not be cloned, a warning message will
be issued but otherwise the process is not stopped.
But if the Association cannot be created for any other reason that's an error and an
UpdateModelFromDatabaseException will be thrown.
Clone the Association with its ReferentialConstraint ( if available ) AssociationSet and AssociationSetMapping . If the ReferentialConstraint is available in the temp artifact but we cannot find matching properties in the existing artifact then the whole Association ( and AssociationSet and AssociationSetMapping ) will not be cloned a warning message will be issued but otherwise the process is not stopped . But if the Association cannot be created for any other reason that ' s an error and an UpdateModelFromDatabaseException will be thrown .
private void CloneAssociation(
            CommandProcessorContext cpc, EFArtifact existingArtifact, Association assocInTempArtifact,
            AssociationEnd end1InTempArtifact, AssociationEnd end2InTempArtifact,
            NavigationProperty navProp1InTempArtifact, NavigationProperty navProp2InTempArtifact,
            ConceptualEntityType end1EntityTypeInExistingArtifact, ConceptualEntityType end2EntityTypeInExistingArtifact,
            Dictionary<EntityType, EntityType> tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact)
        {
            Association newAssocInExistingArtifact = null;
            AssociationEnd newAssocEnd1 = null;
            AssociationEnd newAssocEnd2 = null;
            if (assocInTempArtifact.ReferentialConstraint == null)
            {
                var cmd = new CreateConceptualAssociationCommand(
                    assocInTempArtifact.LocalName.Value,
                    end1EntityTypeInExistingArtifact, end1InTempArtifact.Multiplicity.Value, navProp1InTempArtifact.LocalName.Value,
                    end2EntityTypeInExistingArtifact, end2InTempArtifact.Multiplicity.Value, navProp2InTempArtifact.LocalName.Value,
                    true, false);
                CommandProcessor.InvokeSingleCommand(cpc, cmd);
                newAssocInExistingArtifact = cmd.CreatedAssociation;
                newAssocEnd1 = cmd.End1;
                newAssocEnd2 = cmd.End2;
            }
            else
            {
                 Note: ShouldCreateAssociationGivenReferentialConstraint() produces 2 sets of information:
                 (1) the sets of matching properties to use if we can find matching properties for the Principal
                 and Dependent roles, and (2) the sets of property names to include in the error message if 
                 we cannot find matching properties for the Principal and Dependent roles.
                 If ShouldCreateAssociationGivenReferentialConstraint() returns true we use the first set of
                 information to create the ReferentialConstraint after having created the Association and
                 AssociationSet. If it returns false we use the second set of information to construct the
                 warning message.
                var refConstraintInTempArtifact = assocInTempArtifact.ReferentialConstraint;
                bool end1IsPrincipalEnd;
                List<Property> principalPropertiesInExistingArtifact;
                List<Property> dependentPropertiesInExistingArtifact;
                List<string> unfoundPrincipalProperties;
                List<string> unfoundDependentProperties;
                if (ShouldCreateAssociationGivenReferentialConstraint(
                    refConstraintInTempArtifact, end1InTempArtifact,
                    end2InTempArtifact, end1EntityTypeInExistingArtifact, end2EntityTypeInExistingArtifact, out end1IsPrincipalEnd,
                    out principalPropertiesInExistingArtifact, out dependentPropertiesInExistingArtifact,
                    out unfoundPrincipalProperties, out unfoundDependentProperties))
                {
                     create the new Association and AssociationSet
                    var cmd = new CreateConceptualAssociationCommand(
                        assocInTempArtifact.LocalName.Value,
                        end1EntityTypeInExistingArtifact, end1InTempArtifact.Multiplicity.Value, navProp1InTempArtifact.LocalName.Value,
                        end2EntityTypeInExistingArtifact, end2InTempArtifact.Multiplicity.Value, navProp2InTempArtifact.LocalName.Value,
                        true, false);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd);
                    newAssocInExistingArtifact = cmd.CreatedAssociation;
                    newAssocEnd1 = cmd.End1;
                    newAssocEnd2 = cmd.End2;
                     Add in the ReferentialConstraint for the new Association
                    if (null != newAssocInExistingArtifact)
                    {
                        AddReferentialConstraintForAssociation(
                            cpc, cmd, end1IsPrincipalEnd, principalPropertiesInExistingArtifact, dependentPropertiesInExistingArtifact);
                    }
                }
                else
                {
                     Unable to find matching properties for the Principal and Dependent roles of 
                     the ReferentialConstraint. So log a warning message.
                    newAssocInExistingArtifact = null;
                    EntityType principalEndEntityType = end1IsPrincipalEnd
                                                            ? end1EntityTypeInExistingArtifact
                                                            : end2EntityTypeInExistingArtifact;
                    EntityType dependentEndEntityType = end1IsPrincipalEnd
                                                            ? end2EntityTypeInExistingArtifact
                                                            : end1EntityTypeInExistingArtifact;
                    LogWarningMessageForReferentialConstraintProperties(
                        assocInTempArtifact.LocalName.Value,
                        principalEndEntityType, dependentEndEntityType, unfoundPrincipalProperties, unfoundDependentProperties);
                     having logged the warning message we do not need to attempt to create
                     the AssociationSetMapping nor throw an exception due to the lack of the
                     created Association - so just return
                    return;
                }
            }
             if we have failed to create an Association at this stage that's a serious error
             so throw an exception to indicate the failure
            if (null == newAssocInExistingArtifact)
            {
                throw new UpdateModelFromDatabaseException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.UpdateFromDatabaseCannotCreateAssociation,
                        assocInTempArtifact.ToPrettyString()));
            }
             update OnDeleteActions to match temp artifact
            UpdateOnDeleteAction(cpc, newAssocEnd1, end1InTempArtifact);
            UpdateOnDeleteAction(cpc, newAssocEnd2, end2InTempArtifact);
             add a new AssociationSetMapping for the new Association
            AddAssociationSetMappingForConceptualAssociation(
                cpc, existingArtifact, assocInTempArtifact,
                newAssocInExistingArtifact, tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact);
        }
private void CloneAssociation ( CommandProcessorContext cpc , EFArtifact existingArtifact , Association assocInTempArtifact , AssociationEnd end1InTempArtifact , AssociationEnd end2InTempArtifact , NavigationProperty navProp1InTempArtifact , NavigationProperty navProp2InTempArtifact , ConceptualEntityType end1EntityTypeInExistingArtifact , ConceptualEntityType end2EntityTypeInExistingArtifact , Dictionary < EntityType , EntityType > tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact ) { Association newAssocInExistingArtifact = null ; AssociationEnd newAssocEnd1 = null ; AssociationEnd newAssocEnd2 = null ; if ( assocInTempArtifact . ReferentialConstraint == null ) { var cmd = new CreateConceptualAssociationCommand ( assocInTempArtifact . LocalName . Value , end1EntityTypeInExistingArtifact , end1InTempArtifact . Multiplicity . Value , navProp1InTempArtifact . LocalName . Value , end2EntityTypeInExistingArtifact , end2InTempArtifact . Multiplicity . Value , navProp2InTempArtifact . LocalName . Value , true , false ) ; CommandProcessor . InvokeSingleCommand ( cpc , cmd ) ; newAssocInExistingArtifact = cmd . CreatedAssociation ; newAssocEnd1 = cmd . End1 ; newAssocEnd2 = cmd . End2 ; } else { var refConstraintInTempArtifact = assocInTempArtifact . ReferentialConstraint ; bool end1IsPrincipalEnd ; List < Property > principalPropertiesInExistingArtifact ; List < Property > dependentPropertiesInExistingArtifact ; List < string > unfoundPrincipalProperties ; List < string > unfoundDependentProperties ; if ( ShouldCreateAssociationGivenReferentialConstraint ( refConstraintInTempArtifact , end1InTempArtifact , end2InTempArtifact , end1EntityTypeInExistingArtifact , end2EntityTypeInExistingArtifact , out end1IsPrincipalEnd , out principalPropertiesInExistingArtifact , out dependentPropertiesInExistingArtifact , out unfoundPrincipalProperties , out unfoundDependentProperties ) ) { var cmd = new CreateConceptualAssociationCommand ( assocInTempArtifact . LocalName . Value , end1EntityTypeInExistingArtifact , end1InTempArtifact . Multiplicity . Value , navProp1InTempArtifact . LocalName . Value , end2EntityTypeInExistingArtifact , end2InTempArtifact . Multiplicity . Value , navProp2InTempArtifact . LocalName . Value , true , false ) ; CommandProcessor . InvokeSingleCommand ( cpc , cmd ) ; newAssocInExistingArtifact = cmd . CreatedAssociation ; newAssocEnd1 = cmd . End1 ; newAssocEnd2 = cmd . End2 ; if ( null != newAssocInExistingArtifact ) { AddReferentialConstraintForAssociation ( cpc , cmd , end1IsPrincipalEnd , principalPropertiesInExistingArtifact , dependentPropertiesInExistingArtifact ) ; } } else { newAssocInExistingArtifact = null ; EntityType principalEndEntityType = end1IsPrincipalEnd ? end1EntityTypeInExistingArtifact : end2EntityTypeInExistingArtifact ; EntityType dependentEndEntityType = end1IsPrincipalEnd ? end2EntityTypeInExistingArtifact : end1EntityTypeInExistingArtifact ; LogWarningMessageForReferentialConstraintProperties ( assocInTempArtifact . LocalName . Value , principalEndEntityType , dependentEndEntityType , unfoundPrincipalProperties , unfoundDependentProperties ) ; return ; } } if ( null == newAssocInExistingArtifact ) { throw new UpdateModelFromDatabaseException ( string . Format ( CultureInfo . CurrentCulture , Resources . UpdateFromDatabaseCannotCreateAssociation , assocInTempArtifact . ToPrettyString ( ) ) ) ; } UpdateOnDeleteAction ( cpc , newAssocEnd1 , end1InTempArtifact ) ; UpdateOnDeleteAction ( cpc , newAssocEnd2 , end2InTempArtifact ) ; AddAssociationSetMappingForConceptualAssociation ( cpc , existingArtifact , assocInTempArtifact , newAssocInExistingArtifact , tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact ) ; }
Clone the Association with its ReferentialConstraint (if available), AssociationSet
and AssociationSetMapping.
Clone the Association with its ReferentialConstraint ( if available ) AssociationSet and AssociationSetMapping .
// if there is no ReferentialConstraint to clone then just try to  // create the Association and AssociationSet // There is a ReferentialConstraint - so we need to check whether we can find matching properties // for the Principal and Dependent roles of the ReferentialConstraint. If we can't find // matching properties then log a warning message and return. Otherwise attempt to create // the Association (and its AssociationSet) followed by a matching ReferentialConstraint. // // Note: ShouldCreateAssociationGivenReferentialConstraint() produces 2 sets of information: // (1) the sets of matching properties to use if we can find matching properties for the Principal // and Dependent roles, and (2) the sets of property names to include in the error message if  // we cannot find matching properties for the Principal and Dependent roles. // If ShouldCreateAssociationGivenReferentialConstraint() returns true we use the first set of // information to create the ReferentialConstraint after having created the Association and // AssociationSet. If it returns false we use the second set of information to construct the // warning message. // create the new Association and AssociationSet // Add in the ReferentialConstraint for the new Association // Unable to find matching properties for the Principal and Dependent roles of  // the ReferentialConstraint. So log a warning message. // having logged the warning message we do not need to attempt to create // the AssociationSetMapping nor throw an exception due to the lack of the // created Association - so just return // if we have failed to create an Association at this stage that's a serious error // so throw an exception to indicate the failure // update OnDeleteActions to match temp artifact // add a new AssociationSetMapping for the new Association
cpc
CommandProcessorContext
CommandProcessorContext for the commands to be issued
CommandProcessorContext for the commands to be issued
existingArtifact
EFArtifact
the existing artifact in which to make these changes
the existing artifact in which to make these changes
assocInTempArtifact
Association
the Association in the temp artifact to be cloned
the Association in the temp artifact to be cloned
end1InTempArtifact
AssociationEnd
the end of the Association in the temp artifact to be cloned to be treated as End1
the end of the Association in the temp artifact to be cloned to be treated as End1
end2InTempArtifact
AssociationEnd
the end of the Association in the temp artifact to be cloned to be treated as End2
the end of the Association in the temp artifact to be cloned to be treated as End2
navProp1InTempArtifact
NavigationProperty
the NavigationProperty for End1 in the temp artifact to be cloned
the NavigationProperty for End1 in the temp artifact to be cloned
navProp2InTempArtifact
NavigationProperty
the NavigationProperty for End2 in the temp artifact to be cloned
the NavigationProperty for End2 in the temp artifact to be cloned
end1EntityTypeInExistingArtifact
ConceptualEntityType
the EntityType in the existing artifact matching the End1 target in the temp artifact
the EntityType in the existing artifact matching the End1 target in the temp artifact
end2EntityTypeInExistingArtifact
ConceptualEntityType
the EntityType in the existing artifact matching the End2 target in the temp artifact
the EntityType in the existing artifact matching the End2 target in the temp artifact
tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact
Dictionary<EntityType, EntityType>
a Dictionary mapping temp artifact EntityTypes which have
been identified as new to their equivalent in the existing artifact
a Dictionary mapping temp artifact EntityTypes which have been identified as new to their equivalent in the existing artifact