Esempio n. 1
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(
                _mode == Mode.EntityType || _mode == Mode.MappingFragment, "Unknown mode set in CreateFragmentScalarPropertyTreeCommand");

            var cp = new CommandProcessor(cpc);
            CreateFragmentComplexPropertyCommand prereqCmd = null;

            for (var i = 0; i < _properties.Count; i++)
            {
                var property = _properties[i];
                var complexConceptualProperty = property as ComplexConceptualProperty;
                if (complexConceptualProperty != null)
                {
                    Debug.Assert(i < _properties.Count - 1, "Last property shouldn't be ComplexConceptualProperty");
                    CreateFragmentComplexPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_conceptualEntityType, complexConceptualProperty, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_mappingFragment, complexConceptualProperty);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentComplexPropertyCommand(prereqCmd, complexConceptualProperty);
                    }

                    prereqCmd = cmd;
                    cp.EnqueueCommand(cmd);
                }
                else
                {
                    Debug.Assert(i == _properties.Count - 1, "This should be the last property");
                    CreateFragmentScalarPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_conceptualEntityType, property, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_mappingFragment, property, _tableColumn);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentScalarPropertyCommand(prereqCmd, property, _tableColumn);
                    }

                    cp.EnqueueCommand(cmd);
                    cp.Invoke();
                    _createdProperty = cmd.ScalarProperty;
                    return;
                }
            }
        }
        private void ProcessMappingFragment(EntityInfo info, EntityType table, MappingFragment frag)
        {
            // move any scalar mappings to this fragment if they aren't there
            foreach (var sp in info.NonKeyScalars)
            {
                Debug.Assert(sp.ColumnName.Target != null, "Found a ScalarProperty with an unknown column binding");

                if (sp.ColumnName.Target.Parent == table
                    && sp.MappingFragment != frag)
                {
                    // delete the old, create the new
                    AddToDeleteList(sp);

                    var cmd = new CreateFragmentScalarPropertyTreeCommand(frag, sp.GetMappedPropertiesList(), sp.ColumnName.Target);
                    var cp = new CommandProcessor(_cpc, cmd);
                    cp.Invoke();
                }
            }

            // move any conditions to this fragment if they aren't there
            foreach (var cond in info.Conditions)
            {
                Debug.Assert(cond.ColumnName.Target != null, "Found a Condition with an unknown column binding");

                if (cond.ColumnName.Target.Parent == table
                    && cond.MappingFragment != frag)
                {
                    // save off the condition information
                    bool? isNull = null;
                    if (cond.IsNull.Value == Condition.IsNullConstant)
                    {
                        isNull = true;
                    }
                    else if (cond.IsNull.Value == Condition.IsNotNullConstant)
                    {
                        isNull = false;
                    }

                    var conditionValue = cond.Value.Value;
                    var column = cond.ColumnName.Target;

                    // delete the old, create the new
                    AddToDeleteList(cond);

                    var cmd = new CreateFragmentConditionCommand(frag, column, isNull, conditionValue);
                    var cp = new CommandProcessor(_cpc, cmd);
                    cp.Invoke();
                }
            }

            // build a list of all of the keys
            var keysToMap = new List<Property>();
            keysToMap.AddRange(info.KeyProperties);

            // move any key scalar mappings to this fragment if they exist in a different one - provided they are for the same table
            foreach (var sp in info.KeyScalars)
            {
                Debug.Assert(sp.ColumnName.Target != null, "Found a ScalarProperty with an unknown column binding");

                if (sp.ColumnName.Target.Parent == table
                    && sp.MappingFragment != frag)
                {
                    var property = sp.Name.Target;
                    var column = sp.ColumnName.Target;

                    // delete the old, create the new
                    AddToDeleteList(sp);

                    var cmd = new CreateFragmentScalarPropertyCommand(frag, property, column);
                    var cp = new CommandProcessor(_cpc, cmd);
                    cp.Invoke();
                }

                // since we've mapped this one now, remove it from our list of things to do
                keysToMap.Remove(sp.Name.Target);
            }

            // if its TPH, all keys need to be here
            // (Note: if it's not TPH the user needs to specify any missing keys manually)
            if (info.InheritanceStrategy == InheritanceMappingStrategy.TablePerHierarchy)
            {
                // loop through the base most type's keys and add those that we haven't mapped
                foreach (var keyRemaining in keysToMap)
                {
                    var sp = FindKeyMappingInAllParents(info, keyRemaining);
                    if (sp != null
                        && sp.ColumnName.Target != null
                        && sp.ColumnName.Target.Parent == table)
                    {
                        var cmd = new CreateFragmentScalarPropertyCommand(frag, sp.Name.Target, sp.ColumnName.Target);
                        var cp = new CommandProcessor(_cpc, cmd);
                        cp.Invoke();
                    }
                }
            }

            // replicate all non-key base type scalars here if the parent uses a Default ETM
            // (since there is no parent IsTypeOf ETM from which to "inherit" them)
            if (info.Parent != null
                && info.Parent.UsesEntityTypeMappingKind(EntityTypeMappingKind.Default))
            {
                // first gather the list of scalars from all parents
                var parentScalars = new List<ScalarProperty>();
                GatherNonKeyScalarsFromAllParents(info.Parent, parentScalars);

                // then build a list of those scalars used in our fragment
                var existingMappedProperties = new HashSet<Property>();
                foreach (var existingScalar in frag.ScalarProperties())
                {
                    existingMappedProperties.Add(existingScalar.Name.Target);
                }

                // finally, add those in that aren't already in the fragment
                foreach (var sp in parentScalars)
                {
                    Debug.Assert(sp.ColumnName.Target != null, "Found a ScalarProperty with an unknown column binding");

                    // don't duplicate and only add those that use the same table as us
                    if (existingMappedProperties.Contains(sp.Name.Target) == false
                        && sp.ColumnName.Target.EntityType == table)
                    {
                        var cmd = new CreateFragmentScalarPropertyTreeCommand(frag, sp.GetMappedPropertiesList(), sp.ColumnName.Target);
                        var cp = new CommandProcessor(_cpc, cmd);
                        cp.Invoke();

                        existingMappedProperties.Add(sp.Name.Target);
                    }
                }
            }

            // make sure that we don't have any extra scalars
            // so gather the list of all SPs we expect to be here
            var expectedMappedProperties = new List<Property>();
            expectedMappedProperties.AddRange(info.KeyProperties);
            expectedMappedProperties.AddRange(info.NonKeyProperties);
            if (info.Parent != null
                && info.Parent.UsesEntityTypeMappingKind(EntityTypeMappingKind.Default))
            {
                GatherNonKeyPropertiesFromAllParents(info.Parent, expectedMappedProperties);
            }

            // remove any that aren't in our expected list
            foreach (var sp in frag.ScalarProperties())
            {
                if (expectedMappedProperties.Contains(sp.Name.Target) == false)
                {
                    AddToDeleteList(sp);
                }
            }
        }
        /// <summary>
        ///     Creates a new MappingFragment in the existing EntityTypeMapping
        ///     based on another MappingFragment (fragToClone) in a different artifact.
        ///     All the other parameters are presumed to already exist in the same artifact
        ///     as the EntityTypeMapping.
        /// </summary>
        internal static MappingFragment CloneMappingFragment(
            CommandProcessorContext cpc, MappingFragment fragToClone,
            EntityTypeMapping existingEntityTypeMapping, StorageEntitySet existingEntitySet)
        {
            var createFragmentCommand = new CreateMappingFragmentCommand(existingEntityTypeMapping, existingEntitySet);
            var cp = new CommandProcessor(cpc, createFragmentCommand);

            cp.Invoke();

            var frag = createFragmentCommand.MappingFragment;

            Debug.Assert(frag != null, "Could not locate or create the required mapping fragment");

            if (frag != null)
            {
                foreach (var sp in fragToClone.ScalarProperties())
                {
                    Property entityProperty = null;
                    if (sp.Name != null &&
                        sp.Name.Target != null &&
                        sp.Name.Target.LocalName != null &&
                        sp.Name.Target.LocalName.Value != null)
                    {
                        entityProperty = ModelHelper.FindPropertyForEntityTypeMapping(
                            existingEntityTypeMapping, sp.Name.Target.LocalName.Value);
                        Debug.Assert(
                            entityProperty != null,
                            "Cannot find Property with name " + sp.Name.Target.LocalName.Value + " for EntityTypeMapping "
                            + existingEntityTypeMapping.ToPrettyString());
                    }

                    Property tableColumn = null;
                    if (frag.StoreEntitySet != null &&
                        frag.StoreEntitySet.Target != null &&
                        frag.StoreEntitySet.Target.EntityType != null &&
                        frag.StoreEntitySet.Target.EntityType.Target != null &&
                        sp.ColumnName != null &&
                        sp.ColumnName.Target != null &&
                        sp.ColumnName.Target.LocalName != null &&
                        sp.ColumnName.Target.LocalName.Value != null)
                    {
                        tableColumn = ModelHelper.FindProperty(
                            frag.StoreEntitySet.Target.EntityType.Target, sp.ColumnName.Target.LocalName.Value);
                        Debug.Assert(
                            tableColumn != null,
                            "Cannot find Property with name " + sp.ColumnName.Target.LocalName.Value + " for EntityType "
                            + frag.StoreEntitySet.Target.EntityType.Target.ToPrettyString());
                    }

                    if (entityProperty != null &&
                        tableColumn != null)
                    {
                        var createScalarCommand = new CreateFragmentScalarPropertyCommand(frag, entityProperty, tableColumn);
                        var cp2 = new CommandProcessor(cpc, createScalarCommand);
                        cp2.Invoke();
                    }
                }
            }

            return(frag);
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(
                _mode == Mode.EntityType || _mode == Mode.MappingFragment, "Unknown mode set in CreateFragmentScalarPropertyTreeCommand");

            var cp = new CommandProcessor(cpc);
            CreateFragmentComplexPropertyCommand prereqCmd = null;
            for (var i = 0; i < _properties.Count; i++)
            {
                var property = _properties[i];
                var complexConceptualProperty = property as ComplexConceptualProperty;
                if (complexConceptualProperty != null)
                {
                    Debug.Assert(i < _properties.Count - 1, "Last property shouldn't be ComplexConceptualProperty");
                    CreateFragmentComplexPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_conceptualEntityType, complexConceptualProperty, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_mappingFragment, complexConceptualProperty);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentComplexPropertyCommand(prereqCmd, complexConceptualProperty);
                    }

                    prereqCmd = cmd;
                    cp.EnqueueCommand(cmd);
                }
                else
                {
                    Debug.Assert(i == _properties.Count - 1, "This should be the last property");
                    CreateFragmentScalarPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_conceptualEntityType, property, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_mappingFragment, property, _tableColumn);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentScalarPropertyCommand(prereqCmd, property, _tableColumn);
                    }

                    cp.EnqueueCommand(cmd);
                    cp.Invoke();
                    _createdProperty = cmd.ScalarProperty;
                    return;
                }
            }
        }
        /// <summary>
        ///     Creates a new MappingFragment in the existing EntityTypeMapping
        ///     based on another MappingFragment (fragToClone) in a different artifact.
        ///     All the other parameters are presumed to already exist in the same artifact
        ///     as the EntityTypeMapping.
        /// </summary>
        internal static MappingFragment CloneMappingFragment(
            CommandProcessorContext cpc, MappingFragment fragToClone,
            EntityTypeMapping existingEntityTypeMapping, StorageEntitySet existingEntitySet)
        {
            var createFragmentCommand = new CreateMappingFragmentCommand(existingEntityTypeMapping, existingEntitySet);
            var cp = new CommandProcessor(cpc, createFragmentCommand);
            cp.Invoke();

            var frag = createFragmentCommand.MappingFragment;
            Debug.Assert(frag != null, "Could not locate or create the required mapping fragment");

            if (frag != null)
            {
                foreach (var sp in fragToClone.ScalarProperties())
                {
                    Property entityProperty = null;
                    if (sp.Name != null
                        && sp.Name.Target != null
                        && sp.Name.Target.LocalName != null
                        && sp.Name.Target.LocalName.Value != null)
                    {
                        entityProperty = ModelHelper.FindPropertyForEntityTypeMapping(
                            existingEntityTypeMapping, sp.Name.Target.LocalName.Value);
                        Debug.Assert(
                            entityProperty != null,
                            "Cannot find Property with name " + sp.Name.Target.LocalName.Value + " for EntityTypeMapping "
                            + existingEntityTypeMapping.ToPrettyString());
                    }

                    Property tableColumn = null;
                    if (frag.StoreEntitySet != null
                        && frag.StoreEntitySet.Target != null
                        && frag.StoreEntitySet.Target.EntityType != null
                        && frag.StoreEntitySet.Target.EntityType.Target != null
                        && sp.ColumnName != null
                        && sp.ColumnName.Target != null
                        && sp.ColumnName.Target.LocalName != null
                        && sp.ColumnName.Target.LocalName.Value != null)
                    {
                        tableColumn = ModelHelper.FindProperty(
                            frag.StoreEntitySet.Target.EntityType.Target, sp.ColumnName.Target.LocalName.Value);
                        Debug.Assert(
                            tableColumn != null,
                            "Cannot find Property with name " + sp.ColumnName.Target.LocalName.Value + " for EntityType "
                            + frag.StoreEntitySet.Target.EntityType.Target.ToPrettyString());
                    }

                    if (entityProperty != null
                        && tableColumn != null)
                    {
                        var createScalarCommand = new CreateFragmentScalarPropertyCommand(frag, entityProperty, tableColumn);
                        var cp2 = new CommandProcessor(cpc, createScalarCommand);
                        cp2.Invoke();
                    }
                }
            }

            return frag;
        }
        /// <summary>
        ///     In the existing artifact create a new C-side Property
        ///     in the existing EntityType  plus a mapping based on the
        ///     C-side and S-side Properties in the temp artifact
        /// </summary>
        private Property CreateNewConceptualPropertyAndMapping(
            CommandProcessorContext cpc,
            Property cSidePropInTempArtifact, Property sSidePropInTempArtifact,
            EntityType existingEntityType)
        {
            Debug.Assert(cSidePropInTempArtifact != null, "Null C-side Property");
            Debug.Assert(cSidePropInTempArtifact.EntityType.EntityModel.IsCSDL, "cSidePropInTempArtifact must be C-side");
            Debug.Assert(sSidePropInTempArtifact != null, "Null S-side Property");
            Debug.Assert(!sSidePropInTempArtifact.EntityType.EntityModel.IsCSDL, "sSidePropInTempArtifact must be S-side");
            Debug.Assert(existingEntityType != null, "Null existing EntityType");
            Debug.Assert(existingEntityType.EntityModel.IsCSDL, "Existing EntityType must be C-side");

            var pcf = new PropertyClipboardFormat(cSidePropInTempArtifact);
            Debug.Assert(
                pcf != null, "Could not construct PropertyClipboardFormat for C-side Property " + cSidePropInTempArtifact.ToPrettyString());

            if (null == pcf)
            {
                return null;
            }
            else
            {
                // store off matching S-side property in the existing 
                // artifact for mapping below
                var sSidePropInExistingArtifact =
                    FindSSidePropInExistingArtifact(sSidePropInTempArtifact);
                Debug.Assert(
                    null != sSidePropInExistingArtifact,
                    "Cannot find S-side Property matching the one in the temp artifact " + sSidePropInTempArtifact.ToPrettyString());

                // create the C-side Property in the existing artifact
                var cmd = new CopyPropertyCommand(pcf, existingEntityType);
                CommandProcessor.InvokeSingleCommand(cpc, cmd);
                var cSidePropInExistingArtifact = cmd.Property;

                // now create the mapping for the C-side Property just created
                if (null != cSidePropInExistingArtifact
                    && null != sSidePropInExistingArtifact)
                {
                    var cmd2 =
                        new CreateFragmentScalarPropertyCommand(
                            existingEntityType,
                            cSidePropInExistingArtifact, sSidePropInExistingArtifact);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd2);
                }

                return cSidePropInExistingArtifact;
            }
        }