예제 #1
0
            protected override void BuildNew(CommandProcessorContext cpc, string propertyName, string propertyType)
            {
                if (StorageEntityType == null ||
                    ConceptualEntityType == null)
                {
                    Debug.Fail("The AssociationSetEndMappingBuilder does not have references to everything it needs");
                    return;
                }

                // try to find the column with this name
                var tableColumn = StorageEntityType.GetFirstNamedChildByLocalName(propertyName, true) as Property;

                if (tableColumn != null)
                {
                    // now see if there is also a property with this name
                    var entityProperty = ConceptualEntityType.GetFirstNamedChildByLocalName(propertyName) as Property;
                    if (entityProperty == null)
                    {
                        // they might be trying to map a key from the base class
                        EntityType topMostBaseType = ConceptualEntityType.ResolvableTopMostBaseType;
                        entityProperty = topMostBaseType.GetFirstNamedChildByLocalName(propertyName) as Property;
                    }

                    // if we have both, create a mapping
                    if (entityProperty != null)
                    {
                        CreateEndScalarPropertyCommand cmd = null;
                        var end = AssociationSetEnd.EndProperty;
                        if (end == null)
                        {
                            // we don't have an end yet, this version will create an end as well as the scalar property
                            cmd = new CreateEndScalarPropertyCommand(
                                AssociationSet.AssociationSetMapping, AssociationSetEnd, entityProperty, tableColumn);
                        }
                        else
                        {
                            cmd = new CreateEndScalarPropertyCommand(end, entityProperty, tableColumn);
                        }

                        CommandProcessor.InvokeSingleCommand(cpc, cmd);
                    }
                }
            }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var endProperty = AssociationSetMapping.EndProperties().FirstOrDefault(
                ep =>
                string.Equals(ep.Name.XAttribute.Value, AssociationSetEnd.GetRefNameForBinding(ep.Name), StringComparison.CurrentCulture));

            // EndProperty does not exist, create it
            if (endProperty == null)
            {
                base.InvokeInternal(cpc);
                endProperty = EndProperty;
                Debug.Assert(endProperty != null, "Could not create end property");
            }

            // Update Scalar properties
            if (endProperty != null)
            {
                var oldScalarProperties = endProperty.ScalarProperties().ToList();
                foreach (var oldProperty in oldScalarProperties)
                {
                    oldProperty.Delete();
                }

                Debug.Assert(
                    ConceptualKeyProperties.Count() == StorageKeyProperties.Count(),
                    "Found different number of keys in storage and conceptual models");

                var conceptualEnumerator = ConceptualKeyProperties.GetEnumerator();
                var storageEnumerator = StorageKeyProperties.GetEnumerator();

                while (conceptualEnumerator.MoveNext()
                       && storageEnumerator.MoveNext())
                {
                    var createEndScalarCommand = new CreateEndScalarPropertyCommand(
                        endProperty, conceptualEnumerator.Current, storageEnumerator.Current);

                    CommandProcessor.InvokeSingleCommand(cpc, createEndScalarCommand);
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var endProperty = AssociationSetMapping.EndProperties().FirstOrDefault(
                ep =>
                string.Equals(ep.Name.XAttribute.Value, AssociationSetEnd.GetRefNameForBinding(ep.Name), StringComparison.CurrentCulture));

            // EndProperty does not exist, create it
            if (endProperty == null)
            {
                base.InvokeInternal(cpc);
                endProperty = EndProperty;
                Debug.Assert(endProperty != null, "Could not create end property");
            }

            // Update Scalar properties
            if (endProperty != null)
            {
                var oldScalarProperties = endProperty.ScalarProperties().ToList();
                foreach (var oldProperty in oldScalarProperties)
                {
                    oldProperty.Delete();
                }

                Debug.Assert(
                    ConceptualKeyProperties.Count() == StorageKeyProperties.Count(),
                    "Found different number of keys in storage and conceptual models");

                var conceptualEnumerator = ConceptualKeyProperties.GetEnumerator();
                var storageEnumerator    = StorageKeyProperties.GetEnumerator();

                while (conceptualEnumerator.MoveNext() &&
                       storageEnumerator.MoveNext())
                {
                    var createEndScalarCommand = new CreateEndScalarPropertyCommand(
                        endProperty, conceptualEnumerator.Current, storageEnumerator.Current);

                    CommandProcessor.InvokeSingleCommand(cpc, createEndScalarCommand);
                }
            }
        }
            protected override void BuildNew(CommandProcessorContext cpc, string propertyName, string propertyType)
            {
                if (StorageEntityType == null
                    || ConceptualEntityType == null)
                {
                    Debug.Fail("The AssociationSetEndMappingBuilder does not have references to everything it needs");
                    return;
                }

                // try to find the column with this name
                var tableColumn = StorageEntityType.GetFirstNamedChildByLocalName(propertyName, true) as Property;
                if (tableColumn != null)
                {
                    // now see if there is also a property with this name
                    var entityProperty = ConceptualEntityType.GetFirstNamedChildByLocalName(propertyName) as Property;
                    if (entityProperty == null)
                    {
                        // they might be trying to map a key from the base class
                        EntityType topMostBaseType = ConceptualEntityType.ResolvableTopMostBaseType;
                        entityProperty = topMostBaseType.GetFirstNamedChildByLocalName(propertyName) as Property;
                    }

                    // if we have both, create a mapping
                    if (entityProperty != null)
                    {
                        CreateEndScalarPropertyCommand cmd = null;
                        var end = AssociationSetEnd.EndProperty;
                        if (end == null)
                        {
                            // we don't have an end yet, this version will create an end as well as the scalar property
                            cmd = new CreateEndScalarPropertyCommand(
                                AssociationSet.AssociationSetMapping, AssociationSetEnd, entityProperty, tableColumn);
                        }
                        else
                        {
                            cmd = new CreateEndScalarPropertyCommand(end, entityProperty, tableColumn);
                        }

                        CommandProcessor.InvokeSingleCommand(cpc, cmd);
                    }
                }
            }
        // <summary>
        //     The mapping view model contains a MappingEndScalarProperty for every key in each end.  The user can clear out the
        //     underlying scalar property, but that doesn't remove or add the MappingEndScalarProperty.  We need the placeholder
        //     in the view model to show the nodes in the Trid even if there isn't a mapping.  Thus, we don't need to call
        //     this.Parent.AddChild(this) since its already there.
        // </summary>
        internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem)
        {
            Debug.Assert(underlyingModelItem != null, "The underlyingModelItem cannot be null");
            var tableColumn = underlyingModelItem as Property;
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(ScalarProperty == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(tableColumn != null, "The tableColumn cannot be null.");
            if (tableColumn == null)
            {
                return;
            }
            Debug.Assert(tableColumn.EntityType.EntityModel.IsCSDL == false, "tableColumn must be a Store-side Property");

            Context = context;

            // find the c-side property based on the passed in name
            var entityProperty = MappingAssociationSetEnd.ConceptualEntityType.GetFirstNamedChildByLocalName(Property) as Property;
            if (entityProperty == null)
            {
                // they might be trying to map a key from the base class
                EntityType topMostBaseType = MappingAssociationSetEnd.ConceptualEntityType.ResolvableTopMostBaseType;
                entityProperty = topMostBaseType.GetFirstNamedChildByLocalName(Property) as Property;
            }
            Debug.Assert(entityProperty != null, "Failed looking up entity property for ScalarProperty.");
            if (entityProperty == null)
            {
                return;
            }

            // create our context if we don't have one
            if (cpc == null)
            {
                cpc = new CommandProcessorContext(
                    Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateScalarProperty);
            }

            // create the right command
            CreateEndScalarPropertyCommand cmd = null;
            var end = MappingAssociationSetEnd.AssociationSetEnd.EndProperty;
            if (end == null)
            {
                // we don't have an end yet, this version will create an end as well as the scalar property
                cmd = new CreateEndScalarPropertyCommand(
                    MappingAssociationSet.AssociationSet.AssociationSetMapping, MappingAssociationSetEnd.AssociationSetEnd, entityProperty,
                    tableColumn);
            }
            else
            {
                cmd = new CreateEndScalarPropertyCommand(end, entityProperty, tableColumn);
            }

            // set up our post event to fix up the view model
            cmd.PostInvokeEvent += (o, eventArgs) =>
                {
                    var sp = cmd.ScalarProperty;
                    Debug.Assert(sp != null, "cmd failed to generate ScalarProperty");

                    // fix up our view model (we don't have to add this to the parent's children collection
                    // because we created a placeholder row already for every key in the entity)
                    ModelItem = sp;
                };

            try
            {
                // now make the change
                var cp = new CommandProcessor(cpc, cmd);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;
                throw;
            }
        }
        private EndProperty CloneEndProperty(
            CommandProcessorContext cpc,
            EndProperty endToClone, AssociationSetMapping asmInExistingArtifact, AssociationSetEnd aseInExistingArtifact,
            Dictionary<EntityType, EntityType> tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact)
        {
            var createEnd = new CreateEndPropertyCommand(asmInExistingArtifact, aseInExistingArtifact);
            CommandProcessor.InvokeSingleCommand(cpc, createEnd);
            var endInExistingArtifact = createEnd.EndProperty;

            if (null == endInExistingArtifact)
            {
                throw new UpdateModelFromDatabaseException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.UpdateFromDatabaseCannotCreateAssociationSetMappingEndProperty,
                        aseInExistingArtifact.ToPrettyString()));
            }

            var existingArtifact = cpc.Artifact;
            Debug.Assert(existingArtifact != null, "existingArtifact is null for endToClone " + endToClone.ToPrettyString());

            foreach (var sp in endToClone.ScalarProperties())
            {
                if (null == sp.Name.Target)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseScalarPropertyNoNameTarget,
                            sp.ToPrettyString()));
                }
                if (null == sp.ColumnName.Target)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseScalarPropertyNoColumnNameTarget,
                            sp.ToPrettyString()));
                }

                var spCSideEntityTypeinTempArtifact = sp.Name.Target.EntityType as ConceptualEntityType;
                if (null == spCSideEntityTypeinTempArtifact)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseAssociationSetMappingCannotFindEntityTypeForProperty,
                            sp.Name.Target.ToPrettyString()));
                }

                var spSSideEntityTypeinTempArtifact = sp.ColumnName.Target.EntityType as StorageEntityType;
                if (null == spSSideEntityTypeinTempArtifact)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseAssociationSetMappingCannotFindEntityTypeForProperty,
                            sp.ColumnName.Target.ToPrettyString()));
                }

                var csdlEntityTypeInExistingArtifact =
                    FindMatchingConceptualEntityTypeInExistingArtifact(
                        spCSideEntityTypeinTempArtifact,
                        tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact);
                if (null == csdlEntityTypeInExistingArtifact)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingEntityType,
                            sp.ToPrettyString(),
                            spCSideEntityTypeinTempArtifact.ToPrettyString()));
                }

                var ssdlEntityTypeInExistingArtifact =
                    FindMatchingStorageEntityTypeInExistingArtifact(spSSideEntityTypeinTempArtifact);
                if (null == ssdlEntityTypeInExistingArtifact)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingEntityType,
                            sp.ToPrettyString(),
                            spSSideEntityTypeinTempArtifact.ToPrettyString()));
                }

                var entityProperty = FindMatchingPropertyInExistingArtifactEntityType(sp.Name.Target, csdlEntityTypeInExistingArtifact);
                if (null == entityProperty)
                {
                    // Cannot find matching property - it must have been unmapped. 
                    // So try to create a new mapped property to which to attach 
                    // this association.

                    // First find S-side Property in temp artifact to which the C-side
                    // Property identified in the AssociationSetMapping is mapped
                    // (Note: cannot use just sp.ColumnName.Target as the S-side Property
                    // used in the AssociationSetMapping can be different from what is used
                    // for the EntitySetMapping in the temp artifact and it is this latter
                    // we need to replicate here).
                    Property sSidePropertyToBeMappedInTempArtifact = null;
                    foreach (var spInTempArtifact in sp.Name.Target.GetAntiDependenciesOfType<ScalarProperty>())
                    {
                        // Ensure that S-side ScalarProperty is from an EntitySetMapping (and not 
                        // an AssociationSetMapping) in the temp artifact.
                        // Can use first one as in temp artifact there is 1:1 mapping.
                        if (null != spInTempArtifact.GetParentOfType(typeof(EntitySetMapping)))
                        {
                            if (null != spInTempArtifact.ColumnName
                                && null != spInTempArtifact.ColumnName.Target)
                            {
                                if (null == sSidePropertyToBeMappedInTempArtifact)
                                {
                                    sSidePropertyToBeMappedInTempArtifact = spInTempArtifact.ColumnName.Target;
                                }
                                else
                                {
                                    // error in temp artifact - there's more than 1 EntitySetMapping ScalarProperty
                                    // mapped to the C-side Property
                                    Debug.Fail(
                                        "C-side Property " + sp.Name.Target.ToPrettyString() +
                                        " has more than 1 ScalarProperty anti-dep with an EntitySetMapping parent. Should be at most 1.");
                                    break;
                                }
                            }
                        }
                    }

                    if (null == sSidePropertyToBeMappedInTempArtifact)
                    {
                        throw new UpdateModelFromDatabaseException(
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Resources.UpdateFromDatabaseAssociationSetMappingCannotFindSSideForCSideProperty,
                                sp.ToPrettyString(),
                                sp.Name.Target.ToPrettyString()));
                    }

                    // Now find the matching S-side Property in the existing artifact
                    var sSidePropertyToBeMappedInExistingArtifact =
                        FindSSidePropInExistingArtifact(sSidePropertyToBeMappedInTempArtifact);
                    if (null == sSidePropertyToBeMappedInExistingArtifact)
                    {
                        throw new UpdateModelFromDatabaseException(
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingSSideProperty,
                                sp.ToPrettyString(),
                                sSidePropertyToBeMappedInTempArtifact.ToPrettyString()));
                    }

                    // Now create a new C-side Property in the existing artifact mapped 
                    // to the S-side Property we just found
                    entityProperty = CreateNewConceptualPropertyAndMapping(
                        cpc, sp.Name.Target, sSidePropertyToBeMappedInTempArtifact,
                        csdlEntityTypeInExistingArtifact);
                    if (null == entityProperty)
                    {
                        throw new UpdateModelFromDatabaseException(
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Resources.UpdateFromDatabaseAssociationSetMappingCannotFindOrCreateMatchingProperty,
                                sp.ToPrettyString(),
                                sp.Name.Target.ToPrettyString(),
                                csdlEntityTypeInExistingArtifact.ToPrettyString()));
                    }
                }

                var tableColumn = FindMatchingPropertyInExistingArtifactEntityType(sp.ColumnName.Target, ssdlEntityTypeInExistingArtifact);
                if (null == tableColumn)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingProperty,
                            sp.ToPrettyString(),
                            sp.ColumnName.Target.ToPrettyString(),
                            ssdlEntityTypeInExistingArtifact.ToPrettyString()));
                }

                var createScalar = new CreateEndScalarPropertyCommand(endInExistingArtifact, entityProperty, tableColumn);
                CommandProcessor.InvokeSingleCommand(cpc, createScalar);
                var existingScalarProp = createScalar.ScalarProperty;
                if (null == existingScalarProp)
                {
                    throw new UpdateModelFromDatabaseException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.UpdateFromDatabaseCannotCreateAssociationSetMappingScalarProperty,
                            entityProperty.ToPrettyString(),
                            tableColumn.ToPrettyString()));
                }
            }

            return endInExistingArtifact;
        }