protected override void InvokeInternal(CommandProcessorContext cpc) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the association to var model = artifact.StorageModel(); // check for uniqueness var assocName = Name; var assocSetName = assocName; if (UniquifyNames) { assocName = ModelHelper.GetUniqueName(typeof(Association), model, assocName); assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName); } else { // check for uniqueness of the association name string msg = null; if (ModelHelper.IsUniqueName(typeof(Association), model, assocName, false, out msg) == false) { throw new InvalidOperationException(msg); } // check for uniqueness of the association set name if (ModelHelper.IsUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocSetName, false, out msg) == false) { throw new InvalidOperationException(msg); } } // create the new item in our model var association = new Association(model, null); association.LocalName.Value = assocName; model.AddAssociation(association); XmlModelHelper.NormalizeAndResolve(association); // create the ends of the association var fkEnd = new AssociationEnd(association, null); fkEnd.Type.SetRefName(FkTable); fkEnd.Role.Value = FkRoleNameOverride ?? ModelHelper.CreateFKAssociationEndName(FkTable.LocalName.Value); if (FkMultiplicityOverride != null) { fkEnd.Multiplicity.Value = FkMultiplicityOverride; } else { fkEnd.Multiplicity.Value = DoesFkFormPk ? ModelConstants.Multiplicity_ZeroOrOne : ModelConstants.Multiplicity_Many; } association.AddAssociationEnd(fkEnd); XmlModelHelper.NormalizeAndResolve(fkEnd); var pkEnd = new AssociationEnd(association, null); pkEnd.Type.SetRefName(PkTable); pkEnd.Role.Value = PkRoleNameOverride ?? ModelHelper.CreatePKAssociationEndName(PkTable.LocalName.Value); if (PkMultiplicityOverride != null) { pkEnd.Multiplicity.Value = PkMultiplicityOverride; } else { pkEnd.Multiplicity.Value = IsNullableFk ? ModelConstants.Multiplicity_ZeroOrOne : ModelConstants.Multiplicity_One; } association.AddAssociationEnd(pkEnd); XmlModelHelper.NormalizeAndResolve(pkEnd); var cmd = new CreateAssociationSetCommand(assocSetName, association, ModelSpace.Storage); CommandProcessor.InvokeSingleCommand(cpc, cmd); var set = cmd.AssociationSet; Debug.Assert(set != null, "failed to create an AssociationSet"); Association = association; _createdAssociationFkEnd = fkEnd; _createdAssociationPkEnd = pkEnd; }
protected override void InvokeInternal(CommandProcessorContext cpc) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the association to var model = artifact.ConceptualModel(); // check for uniqueness of the assocation and association set names // if uniquifyNames is true then make them unique, otherwise throw // an exception if they're not (always uniquify associationSetName // regardless as we get bugs if not) var assocName = Name; var assocSetName = assocName; if (UniquifyNames) { assocName = ModelHelper.GetUniqueName(typeof(Association), model, assocName); assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName); // ensure unique NavigationProperty names if (ShouldCreateNavigationPropertyEnd1 && !ModelHelper.IsUniquePropertyName(End1Entity, NavigationPropertyInEnd1Entity, true) || NavigationPropertyInEnd1Entity == End1Entity.LocalName.Value) { var namesToAvoid = new HashSet<string>(); namesToAvoid.Add(End1Entity.LocalName.Value); namesToAvoid.Add(NavigationPropertyInEnd2Entity); NavigationPropertyInEnd1Entity = ModelHelper.GetUniqueConceptualPropertyName( NavigationPropertyInEnd1Entity, End1Entity, namesToAvoid); } if (ShouldCreateNavigationPropertyEnd2 && !ModelHelper.IsUniquePropertyName(End2Entity, NavigationPropertyInEnd2Entity, true) || NavigationPropertyInEnd2Entity == End2Entity.LocalName.Value) { var namesToAvoid = new HashSet<string> { End2Entity.LocalName.Value, NavigationPropertyInEnd1Entity }; NavigationPropertyInEnd2Entity = ModelHelper.GetUniqueConceptualPropertyName( NavigationPropertyInEnd2Entity, End2Entity, namesToAvoid); } } else { assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName); string msg = null; if (!ModelHelper.IsUniqueName(typeof(Association), model, assocName, false, out msg)) { throw new InvalidOperationException(msg); } else if (!ModelHelper.IsUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocSetName, false, out msg)) { throw new InvalidOperationException(msg); } else if (ShouldCreateNavigationPropertyEnd1 && (!ModelHelper.IsUniquePropertyName(End1Entity, NavigationPropertyInEnd1Entity, true))) { msg = string.Format(CultureInfo.CurrentCulture, Resources.NAME_NOT_UNIQUE, NavigationPropertyInEnd1Entity); throw new InvalidOperationException(msg); } else if (ShouldCreateNavigationPropertyEnd2 && (!ModelHelper.IsUniquePropertyName(End2Entity, NavigationPropertyInEnd2Entity, true))) { msg = string.Format(CultureInfo.CurrentCulture, Resources.NAME_NOT_UNIQUE, NavigationPropertyInEnd2Entity); throw new InvalidOperationException(msg); } else if (NavigationPropertyInEnd1Entity == End1Entity.LocalName.Value) { msg = string.Format( CultureInfo.CurrentCulture, Resources.NavPropNameSameAsContainer, NavigationPropertyInEnd1Entity); throw new InvalidOperationException(msg); } else if (NavigationPropertyInEnd2Entity == End2Entity.LocalName.Value) { msg = string.Format( CultureInfo.CurrentCulture, Resources.NavPropNameSameAsContainer, NavigationPropertyInEnd2Entity); throw new InvalidOperationException(msg); } } // create the new item in our model var association = new Association(model, null); association.LocalName.Value = assocName; model.AddAssociation(association); XmlModelHelper.NormalizeAndResolve(association); // create the first end _end1 = new AssociationEnd(association, null); _end1.Type.SetRefName(End1Entity); _end1.Role.Value = End1Entity.LocalName.Value; _end1.Multiplicity.Value = End1Multiplicity; association.AddAssociationEnd(_end1); XmlModelHelper.NormalizeAndResolve(_end1); // create the second end _end2 = new AssociationEnd(association, null); _end2.Type.SetRefName(End2Entity); var endRoleValue = End2Entity.LocalName.Value; if (_end1.Role.Value.Equals(endRoleValue)) { // avoid duplicate Role values between the two ends. This will occur in self-associations. // Appending "1" is consistent with how model-gen chooses a unique name. endRoleValue = endRoleValue + "1"; } _end2.Role.Value = endRoleValue; _end2.Multiplicity.Value = End2Multiplicity; association.AddAssociationEnd(_end2); XmlModelHelper.NormalizeAndResolve(_end2); // create the association set for this association var cmd = new CreateAssociationSetCommand(assocSetName, association); CommandProcessor.InvokeSingleCommand(cpc, cmd); var set = cmd.AssociationSet; Debug.Assert(set != null, "unable to create association set"); CreateNavigationPropertyCommand navcmd; if (ShouldCreateNavigationPropertyEnd1) { navcmd = new CreateNavigationPropertyCommand(NavigationPropertyInEnd1Entity, End1Entity, association, _end1, _end2); CommandProcessor.InvokeSingleCommand(cpc, navcmd); } if (ShouldCreateNavigationPropertyEnd2) { navcmd = new CreateNavigationPropertyCommand(NavigationPropertyInEnd2Entity, End2Entity, association, _end2, _end1); CommandProcessor.InvokeSingleCommand(cpc, navcmd); } if (ShouldCreateForeignKeyProperties) { CreateForeignKeyProperties.AddRule(cpc, association); } CreatedAssociation = association; }