protected override void InvokeInternal(CommandProcessorContext cpc) { // make sure that there isn't an ETM of this kind already var entityTypeMapping = ModelHelper.FindEntityTypeMapping(cpc, _entityType, _kind, false); Debug.Assert(entityTypeMapping == null, "We are calling CreateEntityTypeMappingCommand and there is already one of this Kind"); if (entityTypeMapping != null) { _created = entityTypeMapping; return; } // see if we can get the EntitySetMapping for our entity (if we weren't passed it) if (_entitySetMapping == null) { var ces = _entityType.EntitySet as ConceptualEntitySet; Debug.Assert(ces != null, "_entityType.EntitySet should be a ConceptualEntitySet"); // find the EntitySetMapping for this type (V1 assumption is that there is only ESM per ES) EntitySetMapping esm = null; foreach (var depMapping in ces.GetAntiDependenciesOfType <EntitySetMapping>()) { esm = depMapping; break; } _entitySetMapping = esm; } // if we still don't have an ESM, create one if (_entitySetMapping == null) { var cmd = new CreateEntitySetMappingCommand( _entityType.Artifact.MappingModel().FirstEntityContainerMapping, _entityType.EntitySet as ConceptualEntitySet); CommandProcessor.InvokeSingleCommand(cpc, cmd); _entitySetMapping = cmd.EntitySetMapping; } Debug.Assert( _entitySetMapping != null, "_entitySetMapping should not be null - we have been unable to find or create an EntitySetMapping"); // create the ETM var etm = new EntityTypeMapping(_entitySetMapping, null, _kind); etm.TypeName.SetRefName(_entityType); _entitySetMapping.AddEntityTypeMapping(etm); XmlModelHelper.NormalizeAndResolve(etm); _created = etm; }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit Debug.Assert( EntityToBeDerived != null && BaseType != null, "InvokeInternal is called when EntityToBeDerived or BaseType is null"); if (EntityToBeDerived == null || BaseType == null) { throw new InvalidOperationException("InvokeInternal is called when EntityToBeDerived or BaseType is null"); } if (EntityToBeDerived.EntitySet != null) { // since we are creating an inheritance, we need to delete EntitySet(s) for entityToBeDerived, // before we do this, move any EntityTypeMappings to the base type's EntitySetMapping var entitySetToDelete = EntityToBeDerived.EntitySet as ConceptualEntitySet; var entitySetMappingToDelete = entitySetToDelete.EntitySetMapping; // if there isn't an ESM, there won't be anything to move if (entitySetMappingToDelete != null) { var entitySetOfBaseType = BaseType.EntitySet as ConceptualEntitySet; if (entitySetOfBaseType != null) { // get the base type's ESM (if it doesn't exist, create one) var entitySetMappingOfBaseType = entitySetOfBaseType.EntitySetMapping; if (entitySetMappingOfBaseType == null) { var entityContainer = EntityToBeDerived.EntityModel.EntityContainer; Debug.Assert(entityContainer != null, "EntityToBeDerived should have an Entity Container"); var createESM = new CreateEntitySetMappingCommand(entityContainer.EntityContainerMapping, entitySetOfBaseType); CommandProcessor.InvokeSingleCommand(cpc, createESM); entitySetMappingOfBaseType = createESM.EntitySetMapping; } // move all of the ETMs var etms = new List <EntityTypeMapping>(); etms.AddRange(entitySetMappingToDelete.EntityTypeMappings()); foreach (var etm in etms) { // here, to work around an xml editor bug, we clone the entity type mapping, instead of re-parenting it etm.Clone(entitySetMappingOfBaseType); // The old EntityTyepMapping will be deleted when we delete the entity set below. } } } // now we can delete the entity set, which will delete the ESM too DeleteEFElementCommand.DeleteInTransaction(cpc, entitySetToDelete); } // remove all properties from derived entity's key (it will inherit the base type's keys now) if (EntityToBeDerived.Key != null) { var propertyRefs = new List <PropertyRef>(EntityToBeDerived.Key.PropertyRefs); foreach (var propertyRef in propertyRefs) { var property = propertyRef.Name.Target; if (property != null) { var setKey = new SetKeyPropertyCommand(property, false, false, true); CommandProcessor.InvokeSingleCommand(cpc, setKey); } } } // set the base type EntityToBeDerived.BaseType.SetRefName(BaseType); // // if there is a referential constraint, then update any principals in the ref constraint to // point to properties in the new entity type. // foreach (var end in EntityToBeDerived.GetAntiDependenciesOfType <AssociationEnd>()) { foreach (var role in end.GetAntiDependenciesOfType <ReferentialConstraintRole>()) { var rc = role.Parent as ReferentialConstraint; if (rc != null && rc.Principal == role) { // // this is the principal, so we want to update any keys in RC to reflect new keys // in the new base type. If the number of keys don't match, we'll delete any leftovers // var keys = BaseType.ResolvableTopMostBaseType.ResolvableKeys.GetEnumerator(); foreach (var pr in rc.Principal.PropertyRefs) { if (keys.MoveNext()) { // update this property ref to reflect the new key in the derived type pr.Name.SetRefName(keys.Current); ItemBinding[] bindings = { pr.Name }; CheckArtifactBindings.ScheduleBindingsForRebind(cpc, bindings); } else { // no more keys in the new base type, so delete this property ref & it's peer // in the dependent section Command cmd = new DeleteReferentialConstraintPropertyRefCommand(pr); // don't invoke this command now, as it will modify the collection we're iterating over CommandProcessor.EnqueueCommand(cmd); } } } } } // rebind and verify EntityToBeDerived.BaseType.Rebind(); Debug.Assert( EntityToBeDerived.BaseType.Status == BindingStatus.Known, "EntityToBeDerived.BaseType.Status should be BindingStatus.Known, instead it is " + EntityToBeDerived.BaseType.Status.ToString()); }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit Debug.Assert(_derivedType != null, "InvokeInternal is called when DerivedType is null."); if (_derivedType == null) { throw new InvalidOperationException("InvokeInternal is called when DerivedType is null."); } // store off some local variables var baseType = _derivedType.BaseType.Target; var baseEntitySet = baseType.EntitySet as ConceptualEntitySet; var baseEntitySetMapping = (baseEntitySet == null ? null : baseEntitySet.EntitySetMapping); // save off a HashSet of all base types up the inheritance tree for searching later var allBaseTypes = new HashSet <EntityType>(); for (var baseEntityType = baseType; baseEntityType != null; baseEntityType = baseEntityType.BaseType.Target) { allBaseTypes.Add(baseEntityType); } // set up list of all derived types down the inheritance tree var derivedAndAllDerivedTypes = new List <ConceptualEntityType>(); derivedAndAllDerivedTypes.Add(_derivedType); derivedAndAllDerivedTypes.AddRange(_derivedType.ResolvableAllDerivedTypes); // remove any mappings which refer to properties which were inherited as these will // no longer be valid when the inheritance is deleted (and would cause the Mapping Details // window to open in non-edit mode). This must be done _before_ proceeding to clone the // EntityTypeMapping below and before we delete the inheritance (i.e. before the // DefaultableValue Target becomes unresolved). var scalarPropsToDelete = new List <ScalarProperty>(); if (allBaseTypes.Count > 0) { foreach (EntityType et in derivedAndAllDerivedTypes) { foreach (var etm in et.GetAntiDependenciesOfType <EntityTypeMapping>()) { foreach (var mf in etm.MappingFragments()) { foreach (var sp in mf.AllScalarProperties()) { var prop = sp.Name.Target; if (prop != null) { // find EntityType of which this Property is a member var propEntityType = prop.GetParentOfType(typeof(EntityType)) as EntityType; if (propEntityType != null && allBaseTypes.Contains(propEntityType)) { // sp references a Property of an EntityType which will no longer // be in the inheritance hierarchy - so delete the mapping scalarPropsToDelete.Add(sp); } } } } } } } // cannot delete the ScalarProperty while enumerating over them - so instead delete in separate loop below foreach (var sp in scalarPropsToDelete) { DeleteEFElementCommand.DeleteInTransaction(cpc, sp); } // remove the inheritance _derivedType.BaseType.SetRefName(null); // re-resolve the derived type. This will set the state of the _derivedType to be resolved (it could be unresolved because base-type binding could have been a duplicate or unknown binding). _derivedType.State = EFElementState.Normalized; _derivedType.Resolve(_derivedType.Artifact.ArtifactSet); // the entity container we want to add it to var entityContainer = _derivedType.EntityModel.EntityContainer; Debug.Assert(entityContainer != null, "DerivedType does not have an Entity Container"); // since this type no longer derives, it is stand alone and needs its own entity set // derive a name for the new entity set and create it var trialSetName = ModelHelper.ConstructProposedEntitySetName(_derivedType.Artifact, _derivedType.LocalName.Value); var ces = new CreateEntitySetCommand(trialSetName, _derivedType, true); CommandProcessor.InvokeSingleCommand(cpc, ces); var newEntitySet = ces.EntitySet as ConceptualEntitySet; // if the old entityset had mappings, then some may need to be moved if (baseEntitySetMapping != null) { // create a new EntitySetMapping for the new EntitySet that we made for the formally derivedType var createESM = new CreateEntitySetMappingCommand(entityContainer.EntityContainerMapping, newEntitySet); CommandProcessor.InvokeSingleCommand(cpc, createESM); var newEntitySetMapping = createESM.EntitySetMapping; // this type no longer derives from the type it used to, so its mappings can no longer // exist under the old EntitySetMapping, so we need to move them // move any EntityTypeMappings from the old EntitySetMapping used by the former base type // to the new one created for the new EntitySet and EntitySetMapping foreach (EntityType changingType in derivedAndAllDerivedTypes) { var etms = new List <EntityTypeMapping>(); etms.AddRange(changingType.GetAntiDependenciesOfType <EntityTypeMapping>()); foreach (var etm in etms) { // here, to work around an xml editor bug, we clone the entity type mapping, instead of re-parenting it var newetm = etm.Clone(newEntitySetMapping); // now delete the old entity type mapping & dispose it. DeleteEFElementCommand.DeleteInTransaction(cpc, etm); } } } // // if there are any referential constraints properties whose principal ends refer to keys in the // old derived type, delete them // foreach (var end in _derivedType.GetAntiDependenciesOfType <AssociationEnd>()) { foreach (var role in end.GetAntiDependenciesOfType <ReferentialConstraintRole>()) { var rc = role.Parent as ReferentialConstraint; if (rc != null && rc.Principal == role) { foreach (var pr in rc.Principal.PropertyRefs) { Command cmd = new DeleteReferentialConstraintPropertyRefCommand(pr); // don't invoke this command now, as it will modify the collection we're iterating over CommandProcessor.EnqueueCommand(cmd); } } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit Debug.Assert( EntityToBeDerived != null && BaseType != null, "InvokeInternal is called when EntityToBeDerived or BaseType is null"); if (EntityToBeDerived == null || BaseType == null) { throw new InvalidOperationException("InvokeInternal is called when EntityToBeDerived or BaseType is null"); } if (EntityToBeDerived.EntitySet != null) { // since we are creating an inheritance, we need to delete EntitySet(s) for entityToBeDerived, // before we do this, move any EntityTypeMappings to the base type's EntitySetMapping var entitySetToDelete = EntityToBeDerived.EntitySet as ConceptualEntitySet; var entitySetMappingToDelete = entitySetToDelete.EntitySetMapping; // if there isn't an ESM, there won't be anything to move if (entitySetMappingToDelete != null) { var entitySetOfBaseType = BaseType.EntitySet as ConceptualEntitySet; if (entitySetOfBaseType != null) { // get the base type's ESM (if it doesn't exist, create one) var entitySetMappingOfBaseType = entitySetOfBaseType.EntitySetMapping; if (entitySetMappingOfBaseType == null) { var entityContainer = EntityToBeDerived.EntityModel.EntityContainer; Debug.Assert(entityContainer != null, "EntityToBeDerived should have an Entity Container"); var createESM = new CreateEntitySetMappingCommand(entityContainer.EntityContainerMapping, entitySetOfBaseType); CommandProcessor.InvokeSingleCommand(cpc, createESM); entitySetMappingOfBaseType = createESM.EntitySetMapping; } // move all of the ETMs var etms = new List<EntityTypeMapping>(); etms.AddRange(entitySetMappingToDelete.EntityTypeMappings()); foreach (var etm in etms) { // here, to work around an xml editor bug, we clone the entity type mapping, instead of re-parenting it etm.Clone(entitySetMappingOfBaseType); // The old EntityTyepMapping will be deleted when we delete the entity set below. } } } // now we can delete the entity set, which will delete the ESM too DeleteEFElementCommand.DeleteInTransaction(cpc, entitySetToDelete); } // remove all properties from derived entity's key (it will inherit the base type's keys now) if (EntityToBeDerived.Key != null) { var propertyRefs = new List<PropertyRef>(EntityToBeDerived.Key.PropertyRefs); foreach (var propertyRef in propertyRefs) { var property = propertyRef.Name.Target; if (property != null) { var setKey = new SetKeyPropertyCommand(property, false, false, true); CommandProcessor.InvokeSingleCommand(cpc, setKey); } } } // set the base type EntityToBeDerived.BaseType.SetRefName(BaseType); // // if there is a referential constraint, then update any principals in the ref constraint to // point to properties in the new entity type. // foreach (var end in EntityToBeDerived.GetAntiDependenciesOfType<AssociationEnd>()) { foreach (var role in end.GetAntiDependenciesOfType<ReferentialConstraintRole>()) { var rc = role.Parent as ReferentialConstraint; if (rc != null && rc.Principal == role) { // // this is the principal, so we want to update any keys in RC to reflect new keys // in the new base type. If the number of keys don't match, we'll delete any leftovers // var keys = BaseType.ResolvableTopMostBaseType.ResolvableKeys.GetEnumerator(); foreach (var pr in rc.Principal.PropertyRefs) { if (keys.MoveNext()) { // update this property ref to reflect the new key in the derived type pr.Name.SetRefName(keys.Current); ItemBinding[] bindings = { pr.Name }; CheckArtifactBindings.ScheduleBindingsForRebind(cpc, bindings); } else { // no more keys in the new base type, so delete this property ref & it's peer // in the dependent section Command cmd = new DeleteReferentialConstraintPropertyRefCommand(pr); // don't invoke this command now, as it will modify the collection we're iterating over CommandProcessor.EnqueueCommand(cmd); } } } } } // rebind and verify EntityToBeDerived.BaseType.Rebind(); Debug.Assert( EntityToBeDerived.BaseType.Status == BindingStatus.Known, "EntityToBeDerived.BaseType.Status should be BindingStatus.Known, instead it is " + EntityToBeDerived.BaseType.Status.ToString()); }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit Debug.Assert(_derivedType != null, "InvokeInternal is called when DerivedType is null."); if (_derivedType == null) { throw new InvalidOperationException("InvokeInternal is called when DerivedType is null."); } // store off some local variables var baseType = _derivedType.BaseType.Target; var baseEntitySet = baseType.EntitySet as ConceptualEntitySet; var baseEntitySetMapping = (baseEntitySet == null ? null : baseEntitySet.EntitySetMapping); // save off a HashSet of all base types up the inheritance tree for searching later var allBaseTypes = new HashSet<EntityType>(); for (var baseEntityType = baseType; baseEntityType != null; baseEntityType = baseEntityType.BaseType.Target) { allBaseTypes.Add(baseEntityType); } // set up list of all derived types down the inheritance tree var derivedAndAllDerivedTypes = new List<ConceptualEntityType>(); derivedAndAllDerivedTypes.Add(_derivedType); derivedAndAllDerivedTypes.AddRange(_derivedType.ResolvableAllDerivedTypes); // remove any mappings which refer to properties which were inherited as these will // no longer be valid when the inheritance is deleted (and would cause the Mapping Details // window to open in non-edit mode). This must be done _before_ proceeding to clone the // EntityTypeMapping below and before we delete the inheritance (i.e. before the // DefaultableValue Target becomes unresolved). var scalarPropsToDelete = new List<ScalarProperty>(); if (allBaseTypes.Count > 0) { foreach (EntityType et in derivedAndAllDerivedTypes) { foreach (var etm in et.GetAntiDependenciesOfType<EntityTypeMapping>()) { foreach (var mf in etm.MappingFragments()) { foreach (var sp in mf.AllScalarProperties()) { var prop = sp.Name.Target; if (prop != null) { // find EntityType of which this Property is a member var propEntityType = prop.GetParentOfType(typeof(EntityType)) as EntityType; if (propEntityType != null && allBaseTypes.Contains(propEntityType)) { // sp references a Property of an EntityType which will no longer // be in the inheritance hierarchy - so delete the mapping scalarPropsToDelete.Add(sp); } } } } } } } // cannot delete the ScalarProperty while enumerating over them - so instead delete in separate loop below foreach (var sp in scalarPropsToDelete) { DeleteEFElementCommand.DeleteInTransaction(cpc, sp); } // remove the inheritance _derivedType.BaseType.SetRefName(null); // re-resolve the derived type. This will set the state of the _derivedType to be resolved (it could be unresolved because base-type binding could have been a duplicate or unknown binding). _derivedType.State = EFElementState.Normalized; _derivedType.Resolve(_derivedType.Artifact.ArtifactSet); // the entity container we want to add it to var entityContainer = _derivedType.EntityModel.EntityContainer; Debug.Assert(entityContainer != null, "DerivedType does not have an Entity Container"); // since this type no longer derives, it is stand alone and needs its own entity set // derive a name for the new entity set and create it var trialSetName = ModelHelper.ConstructProposedEntitySetName(_derivedType.Artifact, _derivedType.LocalName.Value); var ces = new CreateEntitySetCommand(trialSetName, _derivedType, true); CommandProcessor.InvokeSingleCommand(cpc, ces); var newEntitySet = ces.EntitySet as ConceptualEntitySet; // if the old entityset had mappings, then some may need to be moved if (baseEntitySetMapping != null) { // create a new EntitySetMapping for the new EntitySet that we made for the formally derivedType var createESM = new CreateEntitySetMappingCommand(entityContainer.EntityContainerMapping, newEntitySet); CommandProcessor.InvokeSingleCommand(cpc, createESM); var newEntitySetMapping = createESM.EntitySetMapping; // this type no longer derives from the type it used to, so its mappings can no longer // exist under the old EntitySetMapping, so we need to move them // move any EntityTypeMappings from the old EntitySetMapping used by the former base type // to the new one created for the new EntitySet and EntitySetMapping foreach (EntityType changingType in derivedAndAllDerivedTypes) { var etms = new List<EntityTypeMapping>(); etms.AddRange(changingType.GetAntiDependenciesOfType<EntityTypeMapping>()); foreach (var etm in etms) { // here, to work around an xml editor bug, we clone the entity type mapping, instead of re-parenting it var newetm = etm.Clone(newEntitySetMapping); // now delete the old entity type mapping & dispose it. DeleteEFElementCommand.DeleteInTransaction(cpc, etm); } } } // // if there are any referential constraints properties whose principal ends refer to keys in the // old derived type, delete them // foreach (var end in _derivedType.GetAntiDependenciesOfType<AssociationEnd>()) { foreach (var role in end.GetAntiDependenciesOfType<ReferentialConstraintRole>()) { var rc = role.Parent as ReferentialConstraint; if (rc != null && rc.Principal == role) { foreach (var pr in rc.Principal.PropertyRefs) { Command cmd = new DeleteReferentialConstraintPropertyRefCommand(pr); // don't invoke this command now, as it will modify the collection we're iterating over CommandProcessor.EnqueueCommand(cmd); } } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // make sure that there isn't an ETM of this kind already var entityTypeMapping = ModelHelper.FindEntityTypeMapping(cpc, _entityType, _kind, false); Debug.Assert(entityTypeMapping == null, "We are calling CreateEntityTypeMappingCommand and there is already one of this Kind"); if (entityTypeMapping != null) { _created = entityTypeMapping; return; } // see if we can get the EntitySetMapping for our entity (if we weren't passed it) if (_entitySetMapping == null) { var ces = _entityType.EntitySet as ConceptualEntitySet; Debug.Assert(ces != null, "_entityType.EntitySet should be a ConceptualEntitySet"); // find the EntitySetMapping for this type (V1 assumption is that there is only ESM per ES) EntitySetMapping esm = null; foreach (var depMapping in ces.GetAntiDependenciesOfType<EntitySetMapping>()) { esm = depMapping; break; } _entitySetMapping = esm; } // if we still don't have an ESM, create one if (_entitySetMapping == null) { var cmd = new CreateEntitySetMappingCommand( _entityType.Artifact.MappingModel().FirstEntityContainerMapping, _entityType.EntitySet as ConceptualEntitySet); CommandProcessor.InvokeSingleCommand(cpc, cmd); _entitySetMapping = cmd.EntitySetMapping; } Debug.Assert( _entitySetMapping != null, "_entitySetMapping should not be null - we have been unable to find or create an EntitySetMapping"); // create the ETM var etm = new EntityTypeMapping(_entitySetMapping, null, _kind); etm.TypeName.SetRefName(_entityType); _entitySetMapping.AddEntityTypeMapping(etm); XmlModelHelper.NormalizeAndResolve(etm); _created = etm; }
/// <summary> /// Creates a new EntitySetMapping in the existing EntityContainerMapping /// based on another EntitySetMapping (esmToClone) in a different artifact. /// Uses the FindMatchingEntityTypeInExistingArtifact() to match EntityTypes /// within the EntitySetMapping. /// </summary> private EntitySetMapping CloneEntitySetMapping( CommandProcessorContext cpc, EntitySetMapping esmToClone, EntityContainerMapping existingEntityContainerMapping, ConceptualEntitySet existingEntitySet, Dictionary<EntityType, EntityType> tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact) { var createESM = new CreateEntitySetMappingCommand(existingEntityContainerMapping, existingEntitySet); CommandProcessor.InvokeSingleCommand(cpc, createESM); var esm = createESM.EntitySetMapping; foreach (var etmToBeCloned in esmToClone.EntityTypeMappings()) { var bindings = etmToBeCloned.TypeName.Bindings; if (bindings.Count != 1) { Debug.Fail( "EntityTypeMapping to be cloned " + etmToBeCloned.ToPrettyString() + " has bindings count = " + bindings.Count + ". We only support 1 binding."); } else { var b = bindings.First(); var etToBeCloned = b.Target as ConceptualEntityType; Debug.Assert(etToBeCloned != null, "EntityType target of binding is not ConceptualEntityType"); var etInExistingArtifact = FindMatchingConceptualEntityTypeInExistingArtifact( etToBeCloned, tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact); if (null != etInExistingArtifact) { CreateEntityTypeMappingCommand.CloneEntityTypeMapping( cpc, etmToBeCloned, esm, etInExistingArtifact, etmToBeCloned.Kind); } else { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseEntitySetMappingCannotFindEntityType, etToBeCloned.ToPrettyString())); } } } return esm; }