/// <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);
            }
        }
示例#3
0
        /// <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);
        }
        /// <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;
        }
示例#9
0
        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());
        }
示例#11
0
        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;
            }
        }
        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;
            }
        }
        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));
                            }
                        }
                    }
                }
            }
        }