Example #1
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            DesignerInfo designerInfo;

            Debug.Assert(cpc.Artifact != null, "Artifact was null");
            if (Association != null &&
                cpc.Artifact != null &&
                cpc.Artifact.DesignerInfo() != null &&
                cpc.Artifact.DesignerInfo().TryGetDesignerInfo(OptionsDesignerInfo.ElementName, out designerInfo))
            {
                // APPDB_SCENARIO: We cannot use referential constraints for 0..1:0..1 or 1:1 associations, since these exist as configured
                //                 0..1:* or 1:* associations and so introducing a referential constraint would cause validation errors.
                // Must use Referential Constraint for 1:0..1 relationship as using an AssociationSetMapping results in illegal reference to the same ID column twice (since the PK is also the FK)
                if (Association.IsOneToZeroOrOne ||
                    (UseReferentialConstraint && !(Association.IsZeroOrOneToZeroOrOne || Association.IsOneToOne)))
                {
                    // We're including fk columns, so the update will consist of a ref constraint
                    var createRefConCommand = new CreateOrUpdateReferentialConstraintCommand(
                        (c, subCpc) =>
                    {
                        var cmd                 = c as CreateOrUpdateReferentialConstraintCommand;
                        cmd.PrincipalEnd        = PrincipalEnd;
                        cmd.DependentEnd        = DependentEnd;
                        cmd.PrincipalProperties = PrincipalProperties;
                        cmd.DependentProperties = DependentProperties;

                        return(cmd.PrincipalEnd != null && cmd.DependentEnd != null);
                    });

                    CommandProcessor.InvokeSingleCommand(cpc, createRefConCommand);
                }
                else
                {
                    // We're not including fk columns, so the update will consist of an association set mapping and a deletes of the fk columns (if they exist)
                    // otherwise update AssociationSetMapping appropriately
                    var createMapCommand = new CreateOrUpdateAssociationSetMappingCommand(
                        (c, subCpc) =>
                    {
                        var cmd                    = c as CreateOrUpdateAssociationSetMappingCommand;
                        cmd.Association            = Association;
                        cmd.AssociationSet         = AssociationSet;
                        cmd.EntityContainerMapping = EntityContainerMapping;
                        cmd.StorageEntitySet       = StorageEntitySet;

                        return(cmd.Association != null && cmd.AssociationSet != null && cmd.EntityContainerMapping != null &&
                               cmd.StorageEntitySet != null);
                    });

                    CommandProcessor.InvokeSingleCommand(cpc, createMapCommand);

                    // Delete the fk properties in the conceptual layer if they exist. Do not delete primary key properties though!
                    if (!IncludeFkProperties)
                    {
                        var propertiesToDelete =
                            DependentProperties.Where(p => p.EntityType != null && !p.EntityType.ResolvableKeys.Contains(p)).ToList();
                        foreach (var p in propertiesToDelete)
                        {
                            var deletePropertyCmd = new DeletePropertyCommand(
                                (c, subCpc) =>
                            {
                                var cmd       = c as DeletePropertyCommand;
                                cmd.EFElement = p;
                                return(cmd.EFElement != null);
                            });

                            CommandProcessor.InvokeSingleCommand(cpc, deletePropertyCmd);
                        }
                    }

                    // Add or update the EndProperty elements for the AssociationSetMapping. Try to work out which end is the principal
                    // end by looking at the multiplicity, since we don't have a referential constraint in this case.
                    AssociationSetEnd principalSetEnd;
                    AssociationSetEnd dependentSetEnd;

                    Debug.Assert(
                        AssociationSet.AssociationSetEnds().First().Role.Target != null,
                        "Role Target for Association End was null, AssociationSetMapping update failed");
                    if (AssociationSet.AssociationSetEnds().First().Role.Target != null)
                    {
                        if (Association.End1.Multiplicity.Value == ModelConstants.Multiplicity_Many)
                        {
                            principalSetEnd = AssociationSet.AssociationSetEnds().Last();
                            dependentSetEnd = AssociationSet.AssociationSetEnds().First();
                        }
                        else
                        {
                            principalSetEnd = AssociationSet.AssociationSetEnds().First();
                            dependentSetEnd = AssociationSet.AssociationSetEnds().Last();
                        }

                        var dependentEndPropertyCmd = new CreateOrUpdateEndPropertyCommand(
                            (c, subCpc) =>
                        {
                            var cmd = c as CreateOrUpdateEndPropertyCommand;
                            cmd.AssociationSetEnd       = dependentSetEnd;
                            cmd.AssociationSetMapping   = createMapCommand.AssociationSetMapping;
                            cmd.StorageKeyProperties    = StorageDependentTypeKeyProperties;
                            cmd.ConceptualKeyProperties =
                                ConceptualDependentType.SafeInheritedAndDeclaredProperties.Where(p => p.IsKeyProperty);

                            return(cmd.AssociationSetEnd != null && cmd.AssociationSetMapping != null);
                        });

                        var principalEndPropertyCmd = new CreateOrUpdateEndPropertyCommand(
                            (c, subCpc) =>
                        {
                            var cmd = c as CreateOrUpdateEndPropertyCommand;
                            cmd.AssociationSetEnd       = principalSetEnd;
                            cmd.AssociationSetMapping   = createMapCommand.AssociationSetMapping;
                            cmd.StorageKeyProperties    = StorageDependentTypeForeignKeyProperties;
                            cmd.ConceptualKeyProperties =
                                ConceptualPrincipalType.SafeInheritedAndDeclaredProperties.Where(p => p.IsKeyProperty);

                            return(cmd.AssociationSetEnd != null && cmd.AssociationSetMapping != null);
                        });

                        CommandProcessor.InvokeSingleCommand(cpc, dependentEndPropertyCmd);
                        CommandProcessor.InvokeSingleCommand(cpc, principalEndPropertyCmd);
                    }
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            DesignerInfo designerInfo;

            Debug.Assert(cpc.Artifact != null, "Artifact was null");
            if (Association != null
                && cpc.Artifact != null
                && cpc.Artifact.DesignerInfo() != null
                && cpc.Artifact.DesignerInfo().TryGetDesignerInfo(OptionsDesignerInfo.ElementName, out designerInfo))
            {
                // APPDB_SCENARIO: We cannot use referential constraints for 0..1:0..1 or 1:1 associations, since these exist as configured
                //                 0..1:* or 1:* associations and so introducing a referential constraint would cause validation errors.
                // Must use Referential Constraint for 1:0..1 relationship as using an AssociationSetMapping results in illegal reference to the same ID column twice (since the PK is also the FK)
                if (Association.IsOneToZeroOrOne
                    || (UseReferentialConstraint && !(Association.IsZeroOrOneToZeroOrOne || Association.IsOneToOne)))
                {
                    // We're including fk columns, so the update will consist of a ref constraint
                    var createRefConCommand = new CreateOrUpdateReferentialConstraintCommand(
                        (c, subCpc) =>
                            {
                                var cmd = c as CreateOrUpdateReferentialConstraintCommand;
                                cmd.PrincipalEnd = PrincipalEnd;
                                cmd.DependentEnd = DependentEnd;
                                cmd.PrincipalProperties = PrincipalProperties;
                                cmd.DependentProperties = DependentProperties;

                                return cmd.PrincipalEnd != null && cmd.DependentEnd != null;
                            });

                    CommandProcessor.InvokeSingleCommand(cpc, createRefConCommand);
                }
                else
                {
                    // We're not including fk columns, so the update will consist of an association set mapping and a deletes of the fk columns (if they exist)
                    // otherwise update AssociationSetMapping appropriately
                    var createMapCommand = new CreateOrUpdateAssociationSetMappingCommand(
                        (c, subCpc) =>
                            {
                                var cmd = c as CreateOrUpdateAssociationSetMappingCommand;
                                cmd.Association = Association;
                                cmd.AssociationSet = AssociationSet;
                                cmd.EntityContainerMapping = EntityContainerMapping;
                                cmd.StorageEntitySet = StorageEntitySet;

                                return cmd.Association != null && cmd.AssociationSet != null && cmd.EntityContainerMapping != null
                                       && cmd.StorageEntitySet != null;
                            });

                    CommandProcessor.InvokeSingleCommand(cpc, createMapCommand);

                    // Delete the fk properties in the conceptual layer if they exist. Do not delete primary key properties though!
                    if (!IncludeFkProperties)
                    {
                        var propertiesToDelete =
                            DependentProperties.Where(p => p.EntityType != null && !p.EntityType.ResolvableKeys.Contains(p)).ToList();
                        foreach (var p in propertiesToDelete)
                        {
                            var deletePropertyCmd = new DeletePropertyCommand(
                                (c, subCpc) =>
                                    {
                                        var cmd = c as DeletePropertyCommand;
                                        cmd.EFElement = p;
                                        return cmd.EFElement != null;
                                    });

                            CommandProcessor.InvokeSingleCommand(cpc, deletePropertyCmd);
                        }
                    }

                    // Add or update the EndProperty elements for the AssociationSetMapping. Try to work out which end is the principal
                    // end by looking at the multiplicity, since we don't have a referential constraint in this case.
                    AssociationSetEnd principalSetEnd;
                    AssociationSetEnd dependentSetEnd;

                    Debug.Assert(
                        AssociationSet.AssociationSetEnds().First().Role.Target != null,
                        "Role Target for Association End was null, AssociationSetMapping update failed");
                    if (AssociationSet.AssociationSetEnds().First().Role.Target != null)
                    {
                        if (Association.End1.Multiplicity.Value == ModelConstants.Multiplicity_Many)
                        {
                            principalSetEnd = AssociationSet.AssociationSetEnds().Last();
                            dependentSetEnd = AssociationSet.AssociationSetEnds().First();
                        }
                        else
                        {
                            principalSetEnd = AssociationSet.AssociationSetEnds().First();
                            dependentSetEnd = AssociationSet.AssociationSetEnds().Last();
                        }

                        var dependentEndPropertyCmd = new CreateOrUpdateEndPropertyCommand(
                            (c, subCpc) =>
                                {
                                    var cmd = c as CreateOrUpdateEndPropertyCommand;
                                    cmd.AssociationSetEnd = dependentSetEnd;
                                    cmd.AssociationSetMapping = createMapCommand.AssociationSetMapping;
                                    cmd.StorageKeyProperties = StorageDependentTypeKeyProperties;
                                    cmd.ConceptualKeyProperties =
                                        ConceptualDependentType.SafeInheritedAndDeclaredProperties.Where(p => p.IsKeyProperty);

                                    return cmd.AssociationSetEnd != null && cmd.AssociationSetMapping != null;
                                });

                        var principalEndPropertyCmd = new CreateOrUpdateEndPropertyCommand(
                            (c, subCpc) =>
                                {
                                    var cmd = c as CreateOrUpdateEndPropertyCommand;
                                    cmd.AssociationSetEnd = principalSetEnd;
                                    cmd.AssociationSetMapping = createMapCommand.AssociationSetMapping;
                                    cmd.StorageKeyProperties = StorageDependentTypeForeignKeyProperties;
                                    cmd.ConceptualKeyProperties =
                                        ConceptualPrincipalType.SafeInheritedAndDeclaredProperties.Where(p => p.IsKeyProperty);

                                    return cmd.AssociationSetEnd != null && cmd.AssociationSetMapping != null;
                                });

                        CommandProcessor.InvokeSingleCommand(cpc, dependentEndPropertyCmd);
                        CommandProcessor.InvokeSingleCommand(cpc, principalEndPropertyCmd);
                    }
                }
            }
        }