Exemple #1
0
        /// <summary>
        ///     Creates a command of that can swap a Navigation Property association ends.
        /// </summary>
        /// <param name="property">The navigation property to change</param>
        /// <param name="association">The association to use.</param>
        /// <param name="end1">The first point to swap</param>
        /// <param name="end2">The second point to swap</param>
        internal ChangeNavigationPropertyCommand(
            NavigationProperty property, Association association, AssociationEnd end1, AssociationEnd end2)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }
            if (association == null)
            {
                throw new ArgumentNullException("association");
            }
            if (end1 == null)
            {
                throw new ArgumentNullException("end1");
            }
            if (end2 == null)
            {
                throw new ArgumentNullException("end2");
            }

            _property    = property;
            _association = association;
            _end1        = end1;
            _end2        = end2;
        }
Exemple #2
0
        public AssociationEndEditor(AssociationEnd associationEnd)
            : this()
        {
            AssociationEnd = associationEnd;

            this.tbRole.Text    = associationEnd.Name;
            this.lClass.Content = associationEnd.Class.Name;
            this.tbLower.Text   = associationEnd.Lower.ToString();
            this.tbUpper.Text   = associationEnd.Upper.ToString();

            switch (associationEnd.Aggregation)
            {
            case AggregationKind.none:
                cbType.SelectedIndex = 0;
                break;

            case AggregationKind.shared:
                cbType.SelectedIndex = 1;
                break;

            case AggregationKind.composite:
                cbType.SelectedIndex = 2;
                break;
            }

            oldKindIndex = cbType.SelectedIndex;
        }
Exemple #3
0
 private void CompareAssociationEnd(AssociationEnd expectedEnd, AssociationEnd actualEnd)
 {
     this.SatisfiesEquals(expectedEnd.RoleName, actualEnd.RoleName, "RoleName not as expeted.");
     this.SatisfiesEquals(expectedEnd.Multiplicity, actualEnd.Multiplicity, "Multiplicity does not match on AssociationEnd '{0}'.", expectedEnd.RoleName);
     this.SatisfiesEquals(expectedEnd.EntityType.FullName, actualEnd.EntityType.FullName, "EntityType name does not match on AssociationEnd '{0}'.", expectedEnd.RoleName);
     this.SatisfiesEquals(expectedEnd.DeleteBehavior, actualEnd.DeleteBehavior, "DeleteBehavior does not match on AssociationEnd '{0}'.", expectedEnd.RoleName);
 }
Exemple #4
0
        private static bool DoesEndNeedCondition(AssociationEnd end, AssociationEnd otherEnd, EntityType associationSetMappingTable)
        {
            if (end.Multiplicity.Value == ModelConstants.Multiplicity_ZeroOrOne)
            {
                return(true);
            }

            var cet = end.Type.Target as ConceptualEntityType;

            Debug.Assert(end.Type.Target != null ? cet != null : true, "EntityType is not a ConceptualEntityType");

            if (cet != null &&
                cet.HasResolvableBaseType)
            {
                // the subtype is mapped using TPH
                EntityType tphTable = null;
                if (IsMappedUsingTph(cet, out tphTable))
                {
                    // the association is not *:*
                    if (!(end.Multiplicity.Value == ModelConstants.Multiplicity_Many &&
                          otherEnd.Multiplicity.Value == ModelConstants.Multiplicity_Many))
                    {
                        // and the association's foreign key is on the TPH side (ergo, the association is mapped to the same table as the TPH hierarchy)
                        if (tphTable == associationSetMappingTable)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        /// <summary>
        ///     Creates a command of that can swap a Navigation Property association ends.
        /// </summary>
        /// <param name="property">The navigation property to change</param>
        /// <param name="association">The association to use.</param>
        /// <param name="end1">The first point to swap</param>
        /// <param name="end2">The second point to swap</param>
        internal ChangeNavigationPropertyCommand(
            NavigationProperty property, Association association, AssociationEnd end1, AssociationEnd end2)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }
            if (association == null)
            {
                throw new ArgumentNullException("association");
            }
            if (end1 == null)
            {
                throw new ArgumentNullException("end1");
            }
            if (end2 == null)
            {
                throw new ArgumentNullException("end2");
            }

            _property = property;
            _association = association;
            _end1 = end1;
            _end2 = end2;
        }
        protected override void OnTypeDescriptorInitialize()
        {
            base.OnTypeDescriptorInitialize();
            if (TypedEFElement != null)
            {
                var ends = TypedEFElement.AssociationEnds();
                if (ends.Count > 0)
                {
                    end1 = ends[0];
                    var et1  = end1.Type.Target;
                    var cet1 = et1 as ConceptualEntityType;
                    if (cet1 != null)
                    {
                        navProp1 = cet1.FindNavigationPropertyForEnd(end1);
                    }
                }
                if (ends.Count > 1)
                {
                    end2 = ends[1];
                    var et2  = end2.Type.Target;
                    var cet2 = et2 as ConceptualEntityType;

                    if (cet2 != null)
                    {
                        navProp2 = cet2.FindNavigationPropertyForEnd(end2);
                    }
                }
                _ref = new ReferentialConstraintProperty();
            }
        }
Exemple #7
0
 public override int GetHashCode()
 {
     unchecked
     {
         return((base.GetHashCode() * 397) ^ (AssociationEnd != null ? AssociationEnd.GetHashCode() : 0));
     }
 }
Exemple #8
0
        /// <summary>
        /// Get navigate result for specified associaion type and end
        /// </summary>
        /// <param name="associationType">The association type.</param>
        /// <param name="toEnd">The end to navigate to.</param>
        /// <returns>The result query entity value(s) for navigate.</returns>
        public QueryValue GetNavigateResult(AssociationType associationType, AssociationEnd toEnd)
        {
            ExceptionUtilities.Assert(this.navigateResultLookup.ContainsKey(associationType), "Invalid AssociationType for Navigate: {0}", associationType.FullName);
            var lookupBasedOnEnd = this.navigateResultLookup[associationType];

            ExceptionUtilities.Assert(lookupBasedOnEnd.ContainsKey(toEnd), "Invalid ToEnd for Navigate: {0}.{1}, from {2}.", associationType.FullName, toEnd.RoleName, (this.Type as QueryEntityType).EntityType.FullName);
            return(lookupBasedOnEnd[toEnd]);
        }
        /// <summary>
        ///     Creates new OnDeleteAction for AssociationEnd or changes existing one
        /// </summary>
        /// <param name="end"></param>
        /// <param name="action"></param>
        internal CreateOnDeleteActionCommand(AssociationEnd end, string action)
        {
            CommandValidation.ValidateAssociationEnd(end);
            ValidateString(action);

            _parentEnd = end;
            _action = action;
        }
Exemple #10
0
 public void RemoveEnd(AssociationEnd end)
 {
     associationEnds.Remove(end);
     if (!associationEnds.Contains(end))
     {
         end.Class.Assocations.Remove(this);
     }
 }
 private static string GetEndRole(AssociationEnd end)
 {
     if (end == null)
     {
         return(String.Empty);
     }
     return(end.Role.Value);
 }
Exemple #12
0
        public void RemoveAssociationEnd(AssociationEnd end)
        {
            RemoveAssociationEndCommmand removeAssociationEndCommmand =
                (RemoveAssociationEndCommmand)RemoveAssociationEndCommmandFactory.Factory().Create(DiagramController.ModelController);

            removeAssociationEndCommmand.AssociationEnd = end;
            removeAssociationEndCommmand.Execute();
        }
        private static void SetEndRole(AssociationEnd end, string value)
        {
            var     cpc = PropertyWindowViewModelHelper.GetCommandProcessorContext();
            Command c   = new ChangeAssociationEndCommand(end, null, value);
            var     cp  = new CommandProcessor(cpc, c);

            cp.Invoke();
        }
 public string GetAssociationReturn(AssociationEnd association)
 {
     if (association.IsCollection())
     {
         return(String.Format("{0} ?? ({0} = new {1}())", association.Name().ToPrivateMember(), association.ConstructorType()));
     }
     return(association.Name().ToPrivateMember());
 }
        /// <summary>
        ///     Creates new OnDeleteAction for AssociationEnd or changes existing one
        /// </summary>
        /// <param name="end"></param>
        /// <param name="action"></param>
        internal CreateOnDeleteActionCommand(AssociationEnd end, string action)
        {
            CommandValidation.ValidateAssociationEnd(end);
            ValidateString(action);

            _parentEnd = end;
            _action    = action;
        }
 private static string GetEndMultiplicity(AssociationEnd end)
 {
     if (end == null)
     {
         return(String.Empty);
     }
     return(end.Multiplicity.Value);
 }
Exemple #17
0
        public void AddCheckConstraint(AssociationEnd associationEnd)
        {
            string checkFunc = null;

            if (associationEnd.MaxMultiplicity == "1" && associationEnd.MinMultiplicity == "1")
            {
                checkFunc = associationEnd.Name().ToPascalCase() + " != null";
            }
            else if (associationEnd.MaxMultiplicity == "*")
            {
                checkFunc = associationEnd.Name().ToPascalCase() + ".Count >= " + associationEnd.MinMultiplicity;
            }
            else
            {
                checkFunc = string.Format("{0}.Count >= {1} && {0}.Count <= {2}", associationEnd.Name().ToPascalCase(), associationEnd.MinMultiplicity, associationEnd.MaxMultiplicity);
            }


        #line default
        #line hidden

        #line 157 "C:\Dev\Intent.Modules\Modules\Intent.Modules.RichDomain\Templates\EntityState\DomainEntityStateTemplate.tt"
            this.Write("                RequiredMultiplcityChecks[\"");


        #line default
        #line hidden

        #line 158 "C:\Dev\Intent.Modules\Modules\Intent.Modules.RichDomain\Templates\EntityState\DomainEntityStateTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(associationEnd.Name().ToPascalCase()));


        #line default
        #line hidden

        #line 158 "C:\Dev\Intent.Modules\Modules\Intent.Modules.RichDomain\Templates\EntityState\DomainEntityStateTemplate.tt"
            this.Write("\"] = () => ");


        #line default
        #line hidden

        #line 158 "C:\Dev\Intent.Modules\Modules\Intent.Modules.RichDomain\Templates\EntityState\DomainEntityStateTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(checkFunc));


        #line default
        #line hidden

        #line 158 "C:\Dev\Intent.Modules\Modules\Intent.Modules.RichDomain\Templates\EntityState\DomainEntityStateTemplate.tt"
            this.Write(" ;\r\n");


        #line default
        #line hidden

        #line 159 "C:\Dev\Intent.Modules\Modules\Intent.Modules.RichDomain\Templates\EntityState\DomainEntityStateTemplate.tt"
        }
Exemple #18
0
        public void ChangeRole(AssociationEnd end, string role)
        {
            RenameElementCommand <AssociationEnd> command = (RenameElementCommand <AssociationEnd>) RenameElementCommandFactory <AssociationEnd> .Factory().Create(DiagramController.ModelController);

            command.NewName        = role;
            command.RenamedElement = end;
            command.AssociatedElements.Add(Association);
            command.Execute();
        }
Exemple #19
0
        public void ChangeAggregation(AssociationEnd end, AggregationKind newAggregation)
        {
            ChangeAssociationAggregationCommand associationAggregationCommand =
                (ChangeAssociationAggregationCommand)ChangeAssociationAggregationCommandFactory.Factory().Create(DiagramController.ModelController);

            associationAggregationCommand.AssociationEnd     = end;
            associationAggregationCommand.NewAggregationKind = newAggregation;
            associationAggregationCommand.Execute();
        }
 private static string GetEndOnDelete(AssociationEnd end)
 {
     if (end != null &&
         end.OnDeleteAction != null)
     {
         return(end.OnDeleteAction.Action.Value);
     }
     return(ModelConstants.OnDeleteAction_None);
 }
        public string CreateForeignKeyPropertyIfApplicable(AssociationEnd association)
        {
            if (association.RelationshipType == RelationshipType.OneToMany)
            {
                return(string.Format("public Guid{0} {1}Id ", association.IsMandatory() ? "" : "?", association.Name().ToPascalCase()) + "{ get; set; }");
            }

            return(String.Empty);
        }
Exemple #22
0
        public static string ConstructorType(this AssociationEnd associationEnd)
        {
            if (associationEnd.IsCollection())
            {
                return("List<" + associationEnd.Class.Name + ">");
            }

            return(associationEnd.Class.Name);
        }
        public AssociationEndViewHelper(Diagram diagram, AssociationViewHelper associationViewHelper, AssociationEnd associationEnd)
            : base(diagram)
        {
            AssociationViewHelper       = associationViewHelper;
            MultiplicityLabelViewHelper = new AssociationLabelViewHelper(diagram);
            RoleLabelViewHelper         = new AssociationLabelViewHelper(diagram);
            AssociationEnd = associationEnd;

            points = new ObservablePointCollection();
        }
Exemple #24
0
 public static string IdentifierName(this AssociationEnd associationEnd)
 {
     if (string.IsNullOrEmpty(associationEnd.Role))
     {
         return(associationEnd.Class.IdentifierType());
     }
     else
     {
         return(StringExtensions.ToPascalCase(associationEnd.Role) + "Id");// associationEnd.Class.IdentifierType();
     }
 }
Exemple #25
0
 private XElement GenerateAssociationEnd(XNamespace xmlNamespace, AssociationEnd end)
 {
     return(new XElement(
                xmlNamespace + "End",
                new XAttribute("Role", end.RoleName),
                new XAttribute("Type", this.GetFullyQualifiedName(end.EntityType)),
                new XAttribute("Multiplicity", this.GetMultiplicityString(end.Multiplicity)),
                this.GenerateDocumentation(xmlNamespace, end),
                this.GenerateOnDelete(end, xmlNamespace),
                this.GenerateAnnotations(xmlNamespace, end)));
 }
Exemple #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PIM_AssociationEnd"/> class.
 /// </summary>
 /// <param name="xCaseCanvas">canvas where the control is placed</param>
 /// <param name="viewHelper">ViewHelper of the control, stores visualization information.</param>
 /// <param name="associationEnd">reprsented association end.</param>
 public PIM_AssociationEnd(XCaseCanvas xCaseCanvas, AssociationEndViewHelper viewHelper, AssociationEnd associationEnd)
     : base(xCaseCanvas)
 {
     PositionChanged += AdjustLabelsPositions;
     AssociationEnd   = associationEnd;
     ViewHelper       = viewHelper;
     if (multiplicityLabel != null)
     {
         multiplicityLabel.ViewHelper = ViewHelper.MultiplicityLabelViewHelper;
     }
 }
Exemple #27
0
        public void ChangeMultiplicity(AssociationEnd end, string newCardinality)
        {
            uint?            lower;
            UnlimitedNatural upper;

            if (!MultiplicityElementController.ParseMultiplicityString(newCardinality, out lower, out upper))
            {
                return;
            }
            MultiplicityElementController.ChangeMultiplicityOfElement(end, Association, lower, upper, DiagramController.ModelController);
        }
Exemple #28
0
        internal void SetNavigateResult(AssociationType associationType, AssociationEnd toEnd, QueryValue result)
        {
            if (!this.navigateResultLookup.ContainsKey(associationType))
            {
                this.navigateResultLookup.Add(associationType, new Dictionary <AssociationEnd, QueryValue>());
            }

            Dictionary <AssociationEnd, QueryValue> lookupBasedOnEnd = this.navigateResultLookup[associationType];

            lookupBasedOnEnd[toEnd] = result;
        }
Exemple #29
0
 public string DeterminePrinciple(AssociationEnd associationEnd)
 {
     if (associationEnd.AssociationType == AssociationType.Composite || associationEnd.OtherAssociationEnd().AssociationType == AssociationType.Aggregation)
     {
         return("Principal");
     }
     if (associationEnd.AssociationType == AssociationType.Aggregation || associationEnd.OtherAssociationEnd().AssociationType == AssociationType.Composite)
     {
         return("Dependent");
     }
     return("");
 }
        /// <summary>
        ///     Creates a ReferentialConstraint in the association that is the parent of the principal
        ///     End.
        /// </summary>
        /// <param name="principalEnd"></param>
        /// <param name="dependentEnd"></param>
        /// <param name="principalProperties"></param>
        /// <param name="dependentProperties"></param>
        internal CreateReferentialConstraintCommand(
            AssociationEnd principalEnd, AssociationEnd dependentEnd,
            IEnumerable <Property> principalProperties, IEnumerable <Property> dependentProperties)
        {
            CommandValidation.ValidateAssociationEnd(principalEnd);
            CommandValidation.ValidateAssociationEnd(dependentEnd);

            PrincipalEnd        = principalEnd;
            DependentEnd        = dependentEnd;
            PrincipalProperties = principalProperties;
            DependentProperties = dependentProperties;
        }
        /// <summary>
        ///     Creates a ReferentialConstraint in the association that is the parent of the principal
        ///     End.
        /// </summary>
        /// <param name="principalEnd"></param>
        /// <param name="dependentEnd"></param>
        /// <param name="principalProperties"></param>
        /// <param name="dependentProperties"></param>
        internal CreateReferentialConstraintCommand(
            AssociationEnd principalEnd, AssociationEnd dependentEnd,
            IEnumerable<Property> principalProperties, IEnumerable<Property> dependentProperties)
        {
            CommandValidation.ValidateAssociationEnd(principalEnd);
            CommandValidation.ValidateAssociationEnd(dependentEnd);

            PrincipalEnd = principalEnd;
            DependentEnd = dependentEnd;
            PrincipalProperties = principalProperties;
            DependentProperties = dependentProperties;
        }
Exemple #32
0
        private XElement GenerateReferentialEnd(string endTypeName, AssociationEnd end, IEnumerable <MemberProperty> properties, XNamespace xmlNamespace)
        {
            var propRefs = from p in properties
                           select new XElement(
                xmlNamespace + "PropertyRef",
                new XAttribute("Name", p.Name));

            return(new XElement(
                       xmlNamespace + endTypeName,
                       new XAttribute("Role", end.RoleName),
                       propRefs));
        }
Exemple #33
0
 private XElement GenerateOnDelete(AssociationEnd end, XNamespace xmlNamespace)
 {
     if (end.DeleteBehavior == OperationAction.Cascade)
     {
         return(new XElement(
                    xmlNamespace + "OnDelete",
                    new XAttribute("Action", "Cascade")));
     }
     else
     {
         return(null);
     }
 }
        internal CreateNavigationPropertyCommand(
            string name, ConceptualEntityType entity, Association association, AssociationEnd end1, AssociationEnd end2)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            Name = name;
            Entity = entity;
            Association = association;
            FromEnd = end1;
            ToEnd = end2;
        }
        private static bool DoesEndNeedCondition(AssociationEnd end, AssociationEnd otherEnd, EntityType associationSetMappingTable)
        {
            if (end.Multiplicity.Value == ModelConstants.Multiplicity_ZeroOrOne)
            {
                return true;
            }

            var cet = end.Type.Target as ConceptualEntityType;
            Debug.Assert(end.Type.Target != null ? cet != null : true, "EntityType is not a ConceptualEntityType");

            if (cet != null
                && cet.HasResolvableBaseType)
            {
                // the subtype is mapped using TPH
                EntityType tphTable = null;
                if (IsMappedUsingTph(cet, out tphTable))
                {
                    // the association is not *:*
                    if (!(end.Multiplicity.Value == ModelConstants.Multiplicity_Many
                          && otherEnd.Multiplicity.Value == ModelConstants.Multiplicity_Many))
                    {
                        // and the association's foreign key is on the TPH side (ergo, the association is mapped to the same table as the TPH hierarchy)
                        if (tphTable == associationSetMappingTable)
                        {
                            return true;
                        }
                    }
                }
            }

            return false;
        }
Exemple #36
0
        private AssociationEnd ReadAssociationEndElement(XmlElement xmlElement, XmlNamespaceManager nsmgr, Dictionary<string, ModelBase> elementIndex)
        {
            var result = new AssociationEnd();
            SetById(elementIndex, xmlElement, result);
            result.Name = xmlElement.Attributes["name"].ValueOr(null);
            if (String.IsNullOrWhiteSpace(result.Name)) result.Name = null;
            result.Visibility = xmlElement.Attributes["visibility"].ValueOr("public");
            result.Aggregation = xmlElement.Attributes["aggregation"].ValueOr("none");
            resolvers.Add((ix) => result.Type = GetById(ix, xmlElement.Attributes["type"].ValueOr(null)) as IModelType);

            var mul = xmlElement.SelectSingleNode("UML:AssociationEnd.multiplicity/UML:Multiplicity/UML:Multiplicity.range/UML:MultiplicityRange", nsmgr);
            if (mul != null)
                result.Multiplicity = mul.Attributes["lower"].ValueOr("0") + ".." + mul.Attributes["upper"].ValueOr("-1").Replace("-1", "*");

            return result;
        }
 internal static void ValidateAssociationEnd(AssociationEnd end)
 {
     ValidateEFElement(end);
 }
        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;
        }
 /// <summary>
 ///     Creates a command of that can change an AssociationEnd
 /// </summary>
 /// <param name="end">The end to change</param>
 /// <param name="multiplicity">Changes the end's multiplicity, this may end up adding or removing conditions on any AssociationSetMappings</param>
 /// <param name="role">Changes the Role property of the end</param>
 internal ChangeAssociationEndCommand(AssociationEnd end, string multiplicity, string role)
 {
     End = end;
     Multiplicity = multiplicity;
     Role = role;
 }
 internal AssociationEnd GetOtherEnd(AssociationEnd oneEnd)
 {
     return End1 == oneEnd ? End2 : End1;
 }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            _property.Relationship.SetRefName(_association);
            _property.Relationship.Rebind();
            Debug.Assert(
                (_property.Relationship.Status == BindingStatus.Known
                 || (_association == null && _property.Relationship.Status == BindingStatus.Undefined)),
                "Rebind for the NavigationProperty failed");

            if (_association != null)
            {
                if (_end1 == null
                    || _end2 == null)
                {
                    var associationEnds = _association.AssociationEnds();
                    Debug.Assert(associationEnds.Count < 3, "AssociationEnds are >= 3");
                    _end1 =
                        associationEnds.Where(
                            r => r.Type != null && r.Type.Status == BindingStatus.Known && r.Type.Target == _property.Parent)
                            .FirstOrDefault();
                    _end2 = associationEnds.Where(
                        r => r.Type != null && r.Type.Status == BindingStatus.Known
                             && ((r.Type.Target != _property.Parent) ||
                                 (r.Type.Target == _property.Parent && r != _end1))).FirstOrDefault();
                }

                // updating association's multiplicity value as opposed to multiplicity itself.
                if (string.IsNullOrEmpty(_multiplicity)
                    && _end2 != null)
                {
                    _multiplicity = _end2.Multiplicity.Value;
                }
            }
            else
            {
                // resets end points when we get a null association
                _end1 = null;
                _end2 = null;
            }

            // rebinds association properties.
            _property.FromRole.SetRefName(_end1);
            _property.FromRole.Rebind();
            _property.ToRole.SetRefName(_end2);
            _property.ToRole.Rebind();

            if (_property.ToRole.Status == BindingStatus.Known
                && string.Compare(_property.ToRole.Target.Multiplicity.Value, _multiplicity, StringComparison.OrdinalIgnoreCase) != 0)
            {
                if (_property.Relationship.Status == BindingStatus.Known)
                {
                    var association = _property.Relationship.Target;

                    _property.ToRole.Target.Multiplicity.Value = _multiplicity;

                    if (association != null
                        && association.AssociationSet != null
                        && association.AssociationSet.AssociationSetMapping != null)
                    {
                        EnforceAssociationSetMappingRules.AddRule(cpc, association.AssociationSet.AssociationSetMapping);
                    }
                }
            }
        }
 internal override bool ParseSingleElement(ICollection<XName> unprocessedElements, XElement elem)
 {
     if (elem.Name.LocalName == AssociationEnd.ElementName)
     {
         var assocEnd = new AssociationEnd(this, elem);
         _ends.Add(assocEnd);
         assocEnd.Parse(unprocessedElements);
     }
     else if (elem.Name.LocalName == ReferentialConstraint.ElementName)
     {
         if (_referentialConstraint != null)
         {
             var msg = String.Format(
                 CultureInfo.CurrentCulture, Resources.TOO_MANY_REFERENTIAL_CONSTRAINTS_IN_ASSOCIATION, LocalName.Value);
             Artifact.AddParseErrorForObject(this, msg, ErrorCodes.TOO_MANY_REFERENTIAL_CONSTRAINTS_IN_ASSOCIATION);
         }
         else
         {
             _referentialConstraint = new ReferentialConstraint(this, elem);
             _referentialConstraint.Parse(unprocessedElements);
         }
     }
     else
     {
         return base.ParseSingleElement(unprocessedElements, elem);
     }
     return true;
 }
        private void cmdPrincipalRole_SelectedIndexChanged(object sender, EventArgs e)
        {
            AssociationEnd principal = null;
            AssociationEnd dependent = null;
            if (cmdPrincipalRole.SelectedItem == _roleListItems[_end1])
            {
                principal = _end1;
                dependent = _end2;
            }
            else if (cmdPrincipalRole.SelectedItem == _roleListItems[_end2])
            {
                principal = _end2;
                dependent = _end1;
            }

            if (principal == _principal)
            {
                return; // no change
            }

            // remember new choice
            _principal = principal;
            _dependent = dependent;

            if (_dependent == null)
            {
                txtDependentRole.Text = string.Empty;
            }
            else
            {
                txtDependentRole.Text = _dependent.Role.Value;
            }

            // clear our lists
            listMappings.Items.Clear();
            _mappingListItems.Clear();

            cmbDependentKey.Items.Clear();
            _dependentListItems.Clear();

            // user might have chosen the blank row
            if (_principal != null
                && _dependent != null)
            {
                PopulateMappingListItems();
                PopulateListView();
                listMappings.Enabled = true;

                // load dependent role keys into the combo box
                if (_dependent.Type.Target != null)
                {
                    cmbDependentKey.Items.Add(_blankDependentKeyListItem);

                    foreach (var key in GetMappableDependentProperties())
                    {
                        var item = new KeyListItem(key.NormalizedName);
                        _dependentListItems.Add(key.NormalizedName, item);

                        cmbDependentKey.Items.Add(item);
                    }

                    // in the SSDL, ref constraints can be to non-key columns
                    if (_association.EntityModel.IsCSDL == false)
                    {
                        foreach (var prop in _dependent.Type.Target.Properties())
                        {
                            if (prop.IsKeyProperty)
                            {
                                continue;
                            }

                            var item = new KeyListItem(prop.NormalizedName);
                            _dependentListItems.Add(prop.NormalizedName, item);

                            cmbDependentKey.Items.Add(item);
                        }
                    }
                }
                cmbDependentKey.Enabled = true;

                // select the first row
                if (listMappings.Items.Count > 0)
                {
                    listMappings.Focus();

                    var lvItem = listMappings.Items[0];
                    lvItem.Selected = true;
                    ShowDependencyKeyComboBox(lvItem);
                }
            }
            else
            {
                listMappings.Enabled = false;
                cmbDependentKey.Enabled = false;
                ChangeDependencyKeyComboBoxVisibility(false);
            }
        }
        internal ReferentialConstraintDialog(Association association)
        {
            if (association == null)
            {
                // this should never be null on current code-paths.
                throw new ArgumentNullException("association");
            }

            _association = association;
            _end1 = _association.AssociationEnds()[0];
            _end2 = _association.AssociationEnds()[1];

            var selfAssociation = (_end1.Type.Target == _end2.Type.Target);

            _roleListItems.Add(_end1, new RoleListItem(_end1, selfAssociation));
            _roleListItems.Add(_end2, new RoleListItem(_end2, selfAssociation));

            InitializeComponent();

            // enable tool tips
            listMappings.ShowItemToolTips = true;

            if (EdmFeatureManager.GetForeignKeysInModelFeatureState(association.Artifact.SchemaVersion).IsEnabled())
            {
                hdrDepedent.Text = DialogsResource.RefConstraintDialog_DependentKeyHeader_SupportFKs;
            }

            // Set the default font to VS shell font.
            var vsFont = VSHelpers.GetVSFont(Services.ServiceProvider);
            if (vsFont != null)
            {
                Font = vsFont;
            }

            // load list of roles
            cmdPrincipalRole.Items.Add(_blankRoleListItem);
            cmdPrincipalRole.Items.Add(_roleListItems[_end1]);
            cmdPrincipalRole.Items.Add(_roleListItems[_end2]);
        }
 internal RoleListItem(AssociationEnd end, bool useRoleName)
 {
     _end = end;
     _useRoleName = useRoleName;
 }
        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;
        }
        /// <summary>
        ///     Determines whether we should create an Association in the existing artifact given
        ///     the ReferentialConstraint and AssociationEnd info from the temp artifact
        /// </summary>
        private static bool ShouldCreateAssociationGivenReferentialConstraint(
            ReferentialConstraint refConstraintInTempArtifact,
            AssociationEnd end1InTempArtifact, AssociationEnd end2InTempArtifact,
            ConceptualEntityType end1EntityTypeInExistingArtifact, ConceptualEntityType end2EntityTypeInExistingArtifact,
            out bool end1IsPrincipalEnd, out List<Property> principalPropertiesInExistingArtifact,
            out List<Property> dependentPropertiesInExistingArtifact, out List<string> unfoundPrincipalProperties,
            out List<string> unfoundDependentProperties)
        {
            end1IsPrincipalEnd = true;
            principalPropertiesInExistingArtifact = new List<Property>();
            unfoundPrincipalProperties = new List<string>();
            dependentPropertiesInExistingArtifact = new List<Property>();
            unfoundDependentProperties = new List<string>();
            ConceptualEntityType principalEndEntityType = null;
            ConceptualEntityType dependentEndEntityType = null;

            if (refConstraintInTempArtifact == null)
            {
                Debug.Fail("Should not have null ReferentialConstraint");
                // no ReferentialConstraint in temp artifact to clone
                return false;
            }

            // determine which end is principal and which dependent
            if (refConstraintInTempArtifact.Principal.Role.Target == end1InTempArtifact)
            {
                Debug.Assert(
                    refConstraintInTempArtifact.Dependent.Role.Target == end2InTempArtifact,
                    "Unexpected end value for Dependent Role of ReferentialConstraint when Principal Role matches end1 from temp artifact");
                end1IsPrincipalEnd = true;
                principalEndEntityType = end1EntityTypeInExistingArtifact;
                dependentEndEntityType = end2EntityTypeInExistingArtifact;
            }
            else if (refConstraintInTempArtifact.Principal.Role.Target == end2InTempArtifact)
            {
                Debug.Assert(
                    refConstraintInTempArtifact.Dependent.Role.Target == end1InTempArtifact,
                    "Unexpected end value for Dependent Role of ReferentialConstraint when Principal Role matches end2 from temp artifact");
                end1IsPrincipalEnd = false;
                principalEndEntityType = end2EntityTypeInExistingArtifact;
                dependentEndEntityType = end1EntityTypeInExistingArtifact;
            }
            else
            {
                Debug.Fail("Couldn't identify principal & dependent end");
                return false;
            }

            // find the principal properties in the existing doc to include in the referential constraint
            foreach (var tempProp in refConstraintInTempArtifact.Principal.Properties)
            {
                var prop = FindMatchingPropertyInExistingArtifactEntityType(tempProp, principalEndEntityType);
                if (prop != null)
                {
                    principalPropertiesInExistingArtifact.Add(prop);
                }
                else
                {
                    unfoundPrincipalProperties.Add(tempProp.LocalName.Value);
                }
            }

            // find the dependent properties in the existing doc to include in the referential constraint
            foreach (var tempProp in refConstraintInTempArtifact.Dependent.Properties)
            {
                var prop = FindMatchingPropertyInExistingArtifactEntityType(tempProp, dependentEndEntityType);
                if (prop != null)
                {
                    dependentPropertiesInExistingArtifact.Add(prop);
                }
                else
                {
                    unfoundDependentProperties.Add(tempProp.LocalName.Value);
                }
            }

            // return true if we found matching properties for all the properties in
            // both the principal and dependent ends, false otherwise
            if (unfoundDependentProperties.Count == 0
                && unfoundPrincipalProperties.Count == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
 internal void AddAssociationEnd(AssociationEnd end)
 {
     _ends.Add(end);
 }
        /// <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);
        }
        private static void UpdateOnDeleteAction(CommandProcessorContext cpc, AssociationEnd newAssocEnd, AssociationEnd tempArtifactAssocEnd)
        {
            Debug.Assert(newAssocEnd != null, "newAssoc should not be null");
            Debug.Assert(tempArtifactAssocEnd != null, "tempArtifactAssocEnd should not be null");
            if (newAssocEnd == null
                || tempArtifactAssocEnd == null)
            {
                return;
            }

            // ensure the OnDeleteAction for the existing artifact is the same as that for the temp artifact
            if (null == tempArtifactAssocEnd.OnDeleteAction
                && null != newAssocEnd.OnDeleteAction)
            {
                // temp artifact has no OnDeleteAction - so delete the one in the existing artifact
                newAssocEnd.OnDeleteAction.Delete();
            }
            else if (null != tempArtifactAssocEnd.OnDeleteAction
                     && null != tempArtifactAssocEnd.OnDeleteAction.Action)
            {
                var tempArtifactOnDeleteAction = tempArtifactAssocEnd.OnDeleteAction.Action.Value;
                if (null == newAssocEnd.OnDeleteAction)
                {
                    // existing artifact has no OnDeleteAction - so create a new one and assign the value from the temp artifact
                    var cmd = new CreateOnDeleteActionCommand(newAssocEnd, tempArtifactOnDeleteAction);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd);
                }
                    // use ordinal comparison as possible values for this attribute are fixed regardless of locale
                else if (false == newAssocEnd.OnDeleteAction.Action.Value.Equals(tempArtifactOnDeleteAction, StringComparison.Ordinal))
                {
                    // existing artifact has an OnDeleteAction but the value does not match - so assign the value from the temp artifact
                    var cmd =
                        new UpdateDefaultableValueCommand<string>(newAssocEnd.OnDeleteAction.Action, tempArtifactOnDeleteAction);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd);
                }
            }
        }