/// <summary> /// This helper function is an easy way to get a new entity type, entity set and key property in the /// new entity type created in the conceptual or storage model. /// NOTE: If the cpc already has an active transaction, these changes will be in that transaction /// and the caller of this helper method must commit it to see these changes commited. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the new entity</param> /// <param name="setName">The name of the new set</param> /// <param name="createKeyProperty">A flag whether to create a new key property or not (sending false creates no new property)</param> /// <param name="propertyName">The name of the new property</param> /// <param name="propertyType">The type of the new property</param> /// <param name="modelSpace">Either Conceptual or Storage</param> /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param> /// <param name="isDefaultName">Flag whether the name is the default for new entity types/sets</param> /// <returns>The new EntityType</returns> internal static EntityType CreateEntityTypeAndEntitySetAndProperty( CommandProcessorContext cpc, string name, string setName, bool createKeyProperty, string propertyName, string propertyType, string propertyStoreGeneratedPattern, ModelSpace modelSpace, bool uniquifyNames, bool isDefaultName = false) { var cp = new CommandProcessor(cpc); var cet = new CreateEntityTypeCommand(name, modelSpace, uniquifyNames); cet.CreateWithDefaultName = isDefaultName; cp.EnqueueCommand(cet); var ces = new CreateEntitySetCommand(setName, cet, modelSpace, uniquifyNames); cp.EnqueueCommand(ces); if (createKeyProperty) { var cpcd = new CreatePropertyCommand(propertyName, cet, propertyType, false); cpcd.IsIdProperty = true; cp.EnqueueCommand(cpcd); var skpc = new SetKeyPropertyCommand(cpcd, true); cp.EnqueueCommand(skpc); var ssgpc = new SetStoreGeneratedPatternCommand(cpcd, propertyStoreGeneratedPattern); cp.EnqueueCommand(ssgpc); } cp.Invoke(); return(cet.EntityType); }
internal override void Invoke(CommandProcessorContext cpc) { var viewModel = _property.GetRootViewModel(); Debug.Assert(viewModel != null, "Unable to find root view model from property: " + _property.Name); if (viewModel != null) { var property = viewModel.ModelXRef.GetExisting(_property) as Property; Debug.Assert(property != null); var cmd = new SetKeyPropertyCommand(property, _property.EntityKey); CommandProcessor.InvokeSingleCommand(cpc, cmd); } }
/// <summary> /// We override this method because we need to do some extra things before /// the normal PreInvoke gets called and our antiDeps are removed /// </summary> /// <param name="cpc"></param> protected override void PreInvoke(CommandProcessorContext cpc) { // Save off the deleted entity type name and property name. We do this // here as well just in case this is a late-bound command. SaveDeletedInformation(); if (Property.IsEntityTypeProperty && Property.IsKeyProperty) { // Remove PropertyRef in Key for this property // Only invoke that for Entity property var setKey = new SetKeyPropertyCommand(Property, false, true); CommandProcessor.InvokeSingleCommand(cpc, setKey); } base.PreInvoke(cpc); }
// the key scenario that this is wanting to cover is where ModelGen has included a discriminator // column in the inferred set of keys in TPH; this column won't be mapped and can't be part of the key private void UnsetUnmappedKeyColumnsFromViews() { foreach (var view in _views) { foreach (var column in view.ResolvableKeys) { var mappings = column.GetAntiDependenciesOfType<ScalarProperty>(); if (mappings.Count == 0) { var command = new SetKeyPropertyCommand(column, false); CommandProcessor.InvokeSingleCommand(_cpc, command); } } } }
private void PropagateKeyToStorageColumn(Property property, Property column) { var table = column.EntityType; if (table != null) { // if we are mapped to a view or a defining query then proceed with key checking var ses = table.EntitySet as StorageEntitySet; if (ses != null && (ses.DefiningQuery != null || ses.StoreSchemaGeneratorTypeIsView)) { // cache this view off to process later if (!_views.Contains(table)) { _views.Add(table); } bool? setKey = null; if (property.IsKeyProperty) { // this column should be a key if (!column.IsKeyProperty) { setKey = true; } } else { // this column should not be a key if (column.IsKeyProperty) { setKey = false; } } if (setKey != null) { var command = new SetKeyPropertyCommand(column, (bool)setKey); CommandProcessor.InvokeSingleCommand(_cpc, command); } } } }
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()); }
/// <summary> /// This helper function is an easy way to get a new entity type, entity set and key property in the /// new entity type created in the conceptual or storage model. /// NOTE: If the cpc already has an active transaction, these changes will be in that transaction /// and the caller of this helper method must commit it to see these changes commited. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the new entity</param> /// <param name="setName">The name of the new set</param> /// <param name="createKeyProperty">A flag whether to create a new key property or not (sending false creates no new property)</param> /// <param name="propertyName">The name of the new property</param> /// <param name="propertyType">The type of the new property</param> /// <param name="modelSpace">Either Conceptual or Storage</param> /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param> /// <param name="isDefaultName">Flag whether the name is the default for new entity types/sets</param> /// <returns>The new EntityType</returns> internal static EntityType CreateEntityTypeAndEntitySetAndProperty( CommandProcessorContext cpc, string name, string setName, bool createKeyProperty, string propertyName, string propertyType, string propertyStoreGeneratedPattern, ModelSpace modelSpace, bool uniquifyNames, bool isDefaultName = false) { var cp = new CommandProcessor(cpc); var cet = new CreateEntityTypeCommand(name, modelSpace, uniquifyNames); cet.CreateWithDefaultName = isDefaultName; cp.EnqueueCommand(cet); var ces = new CreateEntitySetCommand(setName, cet, modelSpace, uniquifyNames); cp.EnqueueCommand(ces); if (createKeyProperty) { var cpcd = new CreatePropertyCommand(propertyName, cet, propertyType, false); cpcd.IsIdProperty = true; cp.EnqueueCommand(cpcd); var skpc = new SetKeyPropertyCommand(cpcd, true); cp.EnqueueCommand(skpc); var ssgpc = new SetStoreGeneratedPatternCommand(cpcd, propertyStoreGeneratedPattern); cp.EnqueueCommand(ssgpc); } cp.Invoke(); return cet.EntityType; }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert(Model != null, "Model was null, could not refresh PKs"); if (Model != null) { foreach (var entityType in Model.EntityTypes()) { var storageEntityType = entityType as StorageEntityType; var conceptualEntityType = entityType as ConceptualEntityType; SchemaQualifiedName entityNameToLookFor = null; if (storageEntityType != null) { var entitySet = storageEntityType.EntitySet as StorageEntitySet; entityNameToLookFor = new SchemaQualifiedName(entitySet.Schema.Value, entitySet.Table.Value); } else if (conceptualEntityType != null) { // If this EntityType has a base type, it should not have any keys. if (conceptualEntityType.BaseType.Target != null) { continue; } entityNameToLookFor = new SchemaQualifiedName(entityType.Name.Value); } Debug.Assert( entityNameToLookFor != null, "Should have created an entity name to look for based off of the current EntityType"); if (entityNameToLookFor != null) { var entityNameToRefresh = EntityTypePks.Keys.FirstOrDefault(name => name.Equals(entityNameToLookFor)); if (entityNameToRefresh != null) { // Update primary key properties that have changed foreach (var prop in entityType.Properties()) { SetKeyPropertyCommand cmd = null; if (prop.IsKeyProperty && EntityTypePks[entityNameToRefresh].All( c => string.Compare(c, prop.Name.Value, StringComparison.Ordinal) != 0)) { // This primary key was removed cmd = new SetKeyPropertyCommand(prop, false); } else if (prop.IsKeyProperty == false && EntityTypePks[entityNameToRefresh].Any( c => string.Compare(c, prop.Name.Value, StringComparison.Ordinal) == 0)) { // This primary key was added cmd = new SetKeyPropertyCommand(prop, true); } if (cmd != null) { CommandProcessor.InvokeSingleCommand(cpc, cmd); } } } else { // If we couldn't find the entity type in the dictionary, then it has no keys. Remove any existing ones. foreach (var keyProp in entityType.ResolvableKeys) { CommandProcessor.InvokeSingleCommand(cpc, new SetKeyPropertyCommand(keyProp, false)); } } } } } }
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) { Debug.Assert(_entityType != null || _complexType != null, "Undefined parent type"); if (_entityType != null) { var propertyName = ModelHelper.GetUniqueConceptualPropertyName(_clipboardProperty.PropertyName, _entityType); if (_clipboardProperty.IsComplexProperty) { _createdProperty = CreateComplexPropertyCommand.CreateComplexProperty( cpc, propertyName, _entityType, _clipboardProperty.PropertyType, _clipboardProperty.ConcurrencyMode, _clipboardProperty.GetterAccessModifier, _clipboardProperty.SetterAccessModifier, _insertPosition); } else if (_clipboardProperty.IsConceptualProperty) { Debug.Assert(_entityType.EntityModel.IsCSDL, "This should be a c-side Entity"); if (_entityType.EntityModel.IsCSDL) { _createdProperty = CreatePropertyCommand.CreateConceptualProperty( cpc, propertyName, _entityType as ConceptualEntityType, _clipboardProperty.PropertyType, _clipboardProperty.IsNullable, _clipboardProperty.Default, _clipboardProperty.ConcurrencyMode, _clipboardProperty.GetterAccessModifier, _clipboardProperty.SetterAccessModifier, _clipboardProperty.MaxLength, _clipboardProperty.FixedLength, _clipboardProperty.Precision, _clipboardProperty.Scale, _clipboardProperty.Unicode, _clipboardProperty.Collation, _clipboardProperty.StoreGeneratedPattern, _insertPosition); } } else { Debug.Assert(_entityType.EntityModel.IsCSDL == false, "This should be a s-side Entity"); if (!_entityType.EntityModel.IsCSDL) { _createdProperty = CreatePropertyCommand.CreateStorageProperty( cpc, propertyName, _entityType as StorageEntityType, _clipboardProperty.PropertyType, _clipboardProperty.IsNullable, _clipboardProperty.Default, _clipboardProperty.MaxLength, DefaultableValueBoolOrNone.GetFromNullableBool(_clipboardProperty.FixedLength), _clipboardProperty.Precision, _clipboardProperty.Scale, DefaultableValueBoolOrNone.GetFromNullableBool(_clipboardProperty.Unicode), _clipboardProperty.Collation, _clipboardProperty.ConcurrencyMode); } } if (_clipboardProperty.IsKeyProperty) { var setKey = new SetKeyPropertyCommand(_createdProperty, true); CommandProcessor.InvokeSingleCommand(cpc, setKey); } AddAnnotations(_clipboardProperty, _createdProperty); } else { var cmd = new CopyComplexTypePropertyCommand(_clipboardProperty, _complexType); CommandProcessor.InvokeSingleCommand(cpc, cmd); _createdProperty = cmd.Property; } }