// <summary> // The mapping view model contains a MappingScalarProperty for every column in the table. The user can clear out the // underlying scalar property, but that doesn't remove or add the MappingScalarProperty. 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 void CreateModelItem(CommandProcessorContext cpc, EditingContext context, List <Property> propertiesChain) { Debug.Assert(propertiesChain != null, "The propertiesChain cannot be null"); 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(MappingStorageEntityType.StorageEntityType != null, "The parent item isn't set up correctly"); Debug.Assert(propertiesChain.Count > 0, "propertiesChain cannot be empty"); Context = context; // local shortcuts EntityType entityType = MappingConceptualEntityType.ConceptualEntityType; EntityType table = MappingStorageEntityType.StorageEntityType; // find the s-side property based on the value stored in this.ColumnName var tableColumn = table.GetFirstNamedChildByLocalName(ColumnName) as Property; Debug.Assert(tableColumn != null, "Failed looking up table column for ScalarProperty."); if (tableColumn == null) { return; } try { // now make the change if (cpc == null) { cpc = new CommandProcessorContext( Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateScalarProperty); } var cmd = new CreateFragmentScalarPropertyTreeCommand(entityType, propertiesChain, tableColumn); cmd.PostInvokeEvent += (o, eventsArgs) => { var sp = cmd.ScalarProperty; Debug.Assert(sp != null, "CreateFragmentScalarPropertyTreeCommand failed to create 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 column in the table) ModelItem = sp; }; var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); } catch { ModelItem = null; throw; } }
internal void ChangeScalarProperty(EditingContext context, List <Property> newPropertiesChain) { if (ModelItem != null) { var propertiesChain = ScalarProperty.GetMappedPropertiesList(); var changeNeeded = false; // is it different than what we have already? if (propertiesChain.Count != newPropertiesChain.Count) { changeNeeded = true; } else { for (var i = 0; i < propertiesChain.Count; i++) { if (propertiesChain[i] != newPropertiesChain[i]) { changeNeeded = true; break; } } } if (changeNeeded) { Debug.Assert(ScalarProperty.ColumnName.Status == BindingStatus.Known, "Table column not found"); if (ScalarProperty.ColumnName.Status == BindingStatus.Known) { // delete old and create new ScalarProperty in one transaction var cpc = new CommandProcessorContext( context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_ChangeScalarProperty); var cmd1 = ScalarProperty.GetDeleteCommand(); var cmd2 = new CreateFragmentScalarPropertyTreeCommand( MappingConceptualEntityType.ConceptualEntityType, newPropertiesChain, ScalarProperty.ColumnName.Target); cmd2.PostInvokeEvent += (o, eventsArgs) => { var sp = cmd2.ScalarProperty; Debug.Assert(sp != null, "CreateFragmentScalarPropertyTreeCommand failed to create a ScalarProperty"); ModelItem = sp; }; var cp = new CommandProcessor(cpc, cmd1, cmd2); try { cp.Invoke(); } catch { ModelItem = null; throw; } } } } else { // if we don't have a scalar property, there is nothing to set this into; // create the scalar property first throw new InvalidOperationException(); } }
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); } } }