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); }
/// <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; } }