internal static Association CreateAssociationAndAssociationSetWithDefaultNames( CommandProcessorContext cpc, ConceptualEntityType end1Entity, ConceptualEntityType end2Entity) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the association to var model = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } // Should have discovered the association name through the behavior service. Going back to default var associationName = ModelHelper.GetUniqueName( typeof(Association), model, end1Entity.LocalName.Value + end2Entity.LocalName.Value); // pluralization service is based on English only for Dev10 IPluralizationService pluralizationService = null; var pluralize = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool( OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeEnablePluralization, OptionsDesignerInfo.EnablePluralizationDefault, artifact); if (pluralize) { pluralizationService = DependencyResolver.GetService <IPluralizationService>(); } var end1Multiplicity = ModelConstants.Multiplicity_One; var end2Multiplicity = ModelConstants.Multiplicity_Many; var proposedEnd1NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end2Entity.LocalName.Value, end2Multiplicity); var end1NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName(proposedEnd1NavPropName, end1Entity); var proposedEnd2NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end1Entity.LocalName.Value, end1Multiplicity); var end2NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName( proposedEnd2NavPropName, end2Entity, new HashSet <string> { end1NavigationPropertyName }); var cac = new CreateConceptualAssociationCommand( associationName, end1Entity, end1Multiplicity, end1NavigationPropertyName, end2Entity, end2Multiplicity, end2NavigationPropertyName, false, // uniquify names false); // create foreign key properties var cp = new CommandProcessor(cpc, cac); cp.Invoke(); return(cac.CreatedAssociation); }
internal override void Invoke(CommandProcessorContext cpc) { var cmd = new CreateConceptualAssociationCommand( _dialog.AssociationName, _dialog.End1Entity, _dialog.End1Multiplicity, _dialog.End1NavigationPropertyName, _dialog.End2Entity, _dialog.End2Multiplicity, _dialog.End2NavigationPropertyName, false, // uniquify names _dialog.CreateForeignKeyProperties); CommandProcessor.InvokeSingleCommand(cpc, cmd); Debug.Assert(cmd.CreatedAssociation != null); }
private void CopyAssociation( CommandProcessorContext cpc, BaseEntityModel model, AssociationClipboardFormat clipboardAssociation , Dictionary <EntityTypeClipboardFormat, EntityType> entitiesMap) { var associationName = ModelHelper.GetUniqueName(typeof(Association), model, clipboardAssociation.AssociationName); var clipboardEntity1 = clipboardAssociation.ClipboardEntity1; var clipboardEntity2 = clipboardAssociation.ClipboardEntity2; var entity1 = entitiesMap[clipboardEntity1] as ConceptualEntityType; var entity2 = entitiesMap[clipboardEntity2] as ConceptualEntityType; Debug.Assert(entity1 != null, "entity1 is not a ConceptualEntityType"); Debug.Assert(entity2 != null, "entity2 is not a ConceptualEntityType"); var navigationPropertyEntity1 = clipboardEntity1.GetNavigationPropertyClipboard( clipboardAssociation.AssociationName, clipboardAssociation.AssociationEndRole1); var navigationPropertyEntity2 = clipboardEntity2.GetNavigationPropertyClipboard( clipboardAssociation.AssociationName, clipboardAssociation.AssociationEndRole2); var navigationPropertyName1 = navigationPropertyEntity1 != null ? ModelHelper.GetUniqueConceptualPropertyName(navigationPropertyEntity1.PropertyName, entity1) : null; string navigationPropertyName2 = null; if (entity1 == entity2) { // if this is a self-association then the NavProp for end2 needs a different name from end1 navigationPropertyName2 = ModelHelper.GetUniqueConceptualPropertyName( (navigationPropertyEntity2 != null ? navigationPropertyEntity2.PropertyName : entity1.LocalName.Value), entity2, new HashSet <string> { navigationPropertyName1 }); } else { navigationPropertyName2 = ModelHelper.GetUniqueConceptualPropertyName( (navigationPropertyEntity2 != null ? navigationPropertyEntity2.PropertyName : entity1.LocalName.Value), entity2); } var cmd = new CreateConceptualAssociationCommand( associationName, entity1, clipboardAssociation.Multiplicity1, navigationPropertyName1, entity2, clipboardAssociation.Multiplicity2, navigationPropertyName2, true, false); CommandProcessor.InvokeSingleCommand(cpc, cmd); // copy nav prop facets & structured annotations if (navigationPropertyEntity1 != null) { var np1 = entity1.FindNavigationPropertyForEnd(cmd.End1); CommandProcessor.InvokeSingleCommand( cpc, new SetNavigationPropertyFacetsCommand( np1, navigationPropertyEntity1.GetterAccessModifier, navigationPropertyEntity1.SetterAccessModifier)); AddAnnotations(navigationPropertyEntity1, np1); } if (navigationPropertyEntity2 != null) { var np2 = entity2.FindNavigationPropertyForEnd(cmd.End2); CommandProcessor.InvokeSingleCommand( cpc, new SetNavigationPropertyFacetsCommand( np2, navigationPropertyEntity2.GetterAccessModifier, navigationPropertyEntity2.SetterAccessModifier)); AddAnnotations(navigationPropertyEntity2, np2); } if (clipboardAssociation.ReferentialConstraint != null) { EntityType principal; EntityType dependent; if (entity1 == FindEntityByClipboardName(clipboardAssociation.ReferentialConstraint.PrincipalEntityName, entitiesMap)) { principal = entity1; dependent = entity2; } else { Debug.Assert( entity2 == FindEntityByClipboardName(clipboardAssociation.ReferentialConstraint.PrincipalEntityName, entitiesMap), "could not find entity using clipboard name " + clipboardAssociation.ReferentialConstraint.PrincipalEntityName); principal = entity2; dependent = entity1; } IEnumerable <Property> principalPropertyList = null; IEnumerable <Property> dependentPropertyList = null; var associationEnds = cmd.CreatedAssociation.AssociationEnds(); if (associationEnds.Count == 2 && (principalPropertyList = ModelHelper.FindProperties(principal, clipboardAssociation.ReferentialConstraint.PrincipalProperties)) != null && (dependentPropertyList = ModelHelper.FindProperties(dependent, clipboardAssociation.ReferentialConstraint.DependentProperties)) != null) { var refCmd = new CreateReferentialConstraintCommand( associationEnds[0], associationEnds[1], principalPropertyList, dependentPropertyList ); CommandProcessor.InvokeSingleCommand(cpc, refCmd); AddAnnotations(clipboardAssociation.ReferentialConstraint, refCmd.ReferentialConstraint); } } // add structured annotations to the association AddAnnotations(clipboardAssociation, cmd.CreatedAssociation); }
private void CopyAssociation( CommandProcessorContext cpc, BaseEntityModel model, AssociationClipboardFormat clipboardAssociation , Dictionary<EntityTypeClipboardFormat, EntityType> entitiesMap) { var associationName = ModelHelper.GetUniqueName(typeof(Association), model, clipboardAssociation.AssociationName); var clipboardEntity1 = clipboardAssociation.ClipboardEntity1; var clipboardEntity2 = clipboardAssociation.ClipboardEntity2; var entity1 = entitiesMap[clipboardEntity1] as ConceptualEntityType; var entity2 = entitiesMap[clipboardEntity2] as ConceptualEntityType; Debug.Assert(entity1 != null, "entity1 is not a ConceptualEntityType"); Debug.Assert(entity2 != null, "entity2 is not a ConceptualEntityType"); var navigationPropertyEntity1 = clipboardEntity1.GetNavigationPropertyClipboard( clipboardAssociation.AssociationName, clipboardAssociation.AssociationEndRole1); var navigationPropertyEntity2 = clipboardEntity2.GetNavigationPropertyClipboard( clipboardAssociation.AssociationName, clipboardAssociation.AssociationEndRole2); var navigationPropertyName1 = navigationPropertyEntity1 != null ? ModelHelper.GetUniqueConceptualPropertyName(navigationPropertyEntity1.PropertyName, entity1) : null; string navigationPropertyName2 = null; if (entity1 == entity2) { // if this is a self-association then the NavProp for end2 needs a different name from end1 navigationPropertyName2 = ModelHelper.GetUniqueConceptualPropertyName( (navigationPropertyEntity2 != null ? navigationPropertyEntity2.PropertyName : entity1.LocalName.Value), entity2, new HashSet<string> { navigationPropertyName1 }); } else { navigationPropertyName2 = ModelHelper.GetUniqueConceptualPropertyName( (navigationPropertyEntity2 != null ? navigationPropertyEntity2.PropertyName : entity1.LocalName.Value), entity2); } var cmd = new CreateConceptualAssociationCommand( associationName, entity1, clipboardAssociation.Multiplicity1, navigationPropertyName1, entity2, clipboardAssociation.Multiplicity2, navigationPropertyName2, true, false); CommandProcessor.InvokeSingleCommand(cpc, cmd); // copy nav prop facets & structured annotations if (navigationPropertyEntity1 != null) { var np1 = entity1.FindNavigationPropertyForEnd(cmd.End1); CommandProcessor.InvokeSingleCommand( cpc, new SetNavigationPropertyFacetsCommand( np1, navigationPropertyEntity1.GetterAccessModifier, navigationPropertyEntity1.SetterAccessModifier)); AddAnnotations(navigationPropertyEntity1, np1); } if (navigationPropertyEntity2 != null) { var np2 = entity2.FindNavigationPropertyForEnd(cmd.End2); CommandProcessor.InvokeSingleCommand( cpc, new SetNavigationPropertyFacetsCommand( np2, navigationPropertyEntity2.GetterAccessModifier, navigationPropertyEntity2.SetterAccessModifier)); AddAnnotations(navigationPropertyEntity2, np2); } if (clipboardAssociation.ReferentialConstraint != null) { EntityType principal; EntityType dependent; if (entity1 == FindEntityByClipboardName(clipboardAssociation.ReferentialConstraint.PrincipalEntityName, entitiesMap)) { principal = entity1; dependent = entity2; } else { Debug.Assert( entity2 == FindEntityByClipboardName(clipboardAssociation.ReferentialConstraint.PrincipalEntityName, entitiesMap), "could not find entity using clipboard name " + clipboardAssociation.ReferentialConstraint.PrincipalEntityName); principal = entity2; dependent = entity1; } IEnumerable<Property> principalPropertyList = null; IEnumerable<Property> dependentPropertyList = null; var associationEnds = cmd.CreatedAssociation.AssociationEnds(); if (associationEnds.Count == 2 && (principalPropertyList = ModelHelper.FindProperties(principal, clipboardAssociation.ReferentialConstraint.PrincipalProperties)) != null && (dependentPropertyList = ModelHelper.FindProperties(dependent, clipboardAssociation.ReferentialConstraint.DependentProperties)) != null) { var refCmd = new CreateReferentialConstraintCommand( associationEnds[0], associationEnds[1], principalPropertyList, dependentPropertyList ); CommandProcessor.InvokeSingleCommand(cpc, refCmd); AddAnnotations(clipboardAssociation.ReferentialConstraint, refCmd.ReferentialConstraint); } } // add structured annotations to the association AddAnnotations(clipboardAssociation, cmd.CreatedAssociation); }
internal static Association CreateAssociationAndAssociationSetWithDefaultNames( CommandProcessorContext cpc, ConceptualEntityType end1Entity, ConceptualEntityType end2Entity) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the association to var model = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } // Should have discovered the association name through the behavior service. Going back to default var associationName = ModelHelper.GetUniqueName( typeof(Association), model, end1Entity.LocalName.Value + end2Entity.LocalName.Value); // pluralization service is based on English only for Dev10 IPluralizationService pluralizationService = null; var pluralize = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool( OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeEnablePluralization, OptionsDesignerInfo.EnablePluralizationDefault, artifact); if (pluralize) { pluralizationService = DependencyResolver.GetService<IPluralizationService>(); } var end1Multiplicity = ModelConstants.Multiplicity_One; var end2Multiplicity = ModelConstants.Multiplicity_Many; var proposedEnd1NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end2Entity.LocalName.Value, end2Multiplicity); var end1NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName(proposedEnd1NavPropName, end1Entity); var proposedEnd2NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end1Entity.LocalName.Value, end1Multiplicity); var end2NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName( proposedEnd2NavPropName, end2Entity, new HashSet<string> { end1NavigationPropertyName }); var cac = new CreateConceptualAssociationCommand( associationName, end1Entity, end1Multiplicity, end1NavigationPropertyName, end2Entity, end2Multiplicity, end2NavigationPropertyName, false, // uniquify names false); // create foreign key properties var cp = new CommandProcessor(cpc, cac); cp.Invoke(); return cac.CreatedAssociation; }
AddReferentialConstraintForAssociation( CommandProcessorContext cpc, CreateConceptualAssociationCommand cmd, bool end1IsPrincipalEnd, List<Property> principalPropertiesInExistingArtifact, List<Property> dependentPropertiesInExistingArtifact) { if (cmd.End1 == null) { Debug.Fail("Should not have null AssociationEnd End1 from CreateConceptualAssociationCommand"); return null; } else if (cmd.End2 == null) { Debug.Fail("Should not have null AssociationEnd End2 from CreateConceptualAssociationCommand"); return null; } //assign principal and dependent ends var principalEndInExistingArtifact = end1IsPrincipalEnd ? cmd.End1 : cmd.End2; var dependentEndInExistingArtifact = end1IsPrincipalEnd ? cmd.End2 : cmd.End1; // now create the referential constraint var rcCmd = new CreateReferentialConstraintCommand( principalEndInExistingArtifact, dependentEndInExistingArtifact, principalPropertiesInExistingArtifact, dependentPropertiesInExistingArtifact); CommandProcessor.InvokeSingleCommand(cpc, rcCmd); var newRC = rcCmd.ReferentialConstraint; return newRC; }
/// <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> 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) { // if there is no ReferentialConstraint to clone then just try to // create the 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; } else { // 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. 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); }