/// <summary> /// This helper function will create a Diagram using default name. /// 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 /// otherwise the diagram will never be created. /// </summary> /// <param name="cpc"></param> /// <returns>The new ComplexType</returns> internal static Diagram CreateDiagramWithDefaultName(CommandProcessorContext cpc) { Debug.Assert(cpc != null, "The passed in CommandProcessorContext is null."); if (cpc != null) { var service = cpc.EditingContext.GetEFArtifactService(); var entityDesignArtifact = service.Artifact as EntityDesignArtifact; if (entityDesignArtifact == null || entityDesignArtifact.DesignerInfo == null || entityDesignArtifact.DesignerInfo.Diagrams == null) { throw new CannotLocateParentItemException(); } var diagramName = ModelHelper.GetUniqueNameWithNumber( typeof(Diagram), entityDesignArtifact.DesignerInfo.Diagrams, Resources.Model_DefaultDiagramName); // go create it var cp = new CommandProcessor(cpc); var cmd = new CreateDiagramCommand(diagramName, entityDesignArtifact.DesignerInfo.Diagrams); cp.EnqueueCommand(cmd); cp.Invoke(); return(cmd.Diagram); } return(null); }
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { if (context == null || context.Instance == null) { return value; } var desc = context.Instance as EFAssociationDescriptor; if (desc != null) { var assoc = desc.WrappedItem as Association; if (assoc != null) { var commands = ReferentialConstraintDialog.LaunchReferentialConstraintDialog(assoc); var cpc = new CommandProcessorContext( desc.EditingContext, EfiTransactionOriginator.PropertyWindowOriginatorId, Resources.Tx_ReferentialContraint); var cp = new CommandProcessor(cpc); foreach (var c in commands) { cp.EnqueueCommand(c); } cp.Invoke(); } } return value; }
protected override void InvokeInternal(CommandProcessorContext cpc) { var cp = new CommandProcessor(cpc); CreateFunctionComplexPropertyCommand preReqCmd = null; for (var i = 0; i < _propertyChain.Count; i++) { var property = _propertyChain[i]; Debug.Assert(property.EntityModel.IsCSDL, "Each Property in the chain must be in the CSDL"); var complexConceptualProperty = property as ComplexConceptualProperty; if (complexConceptualProperty != null) { Debug.Assert(i < _propertyChain.Count - 1, "Last property shouldn't be ComplexConceptualProperty"); CreateFunctionComplexPropertyCommand cmd = null; if (preReqCmd == null) { // first property has a mapping whose parent is the ModificationFunction itself cmd = new CreateFunctionComplexPropertyCommand(_modificationFunction, complexConceptualProperty); } else { // later properties have a mapping whose parent is the ComplexProperty produced from the previous command cmd = new CreateFunctionComplexPropertyCommand(preReqCmd, complexConceptualProperty); } // set up the prereq Command to use for next time around this loop and for the // CreateFunctionScalarPropertyCommand below preReqCmd = cmd; // enqueue the command cp.EnqueueCommand(cmd); } else { Debug.Assert(i == _propertyChain.Count - 1, "This should be the last property"); CreateFunctionScalarPropertyCommand cmd = null; if (preReqCmd == null) { // create the FunctionScalarProperty command without any other properties in the property chain cmd = new CreateFunctionScalarPropertyCommand( _modificationFunction, property, _navPropPointingToProperty, _parameter, _version); } else { // create the FunctionScalarProperty command using the command for the previous property in the property chain cmd = new CreateFunctionScalarPropertyCommand(preReqCmd, property, _navPropPointingToProperty, _parameter, _version); } cp.EnqueueCommand(cmd); cp.Invoke(); _createdProperty = cmd.FunctionScalarProperty; if (_createdProperty != null) { XmlModelHelper.NormalizeAndResolve(_createdProperty); } return; } } }
/// <summary> /// This helper function will create a Diagram using default name. /// 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 /// otherwise the diagram will never be created. /// </summary> /// <param name="cpc"></param> /// <returns>The new ComplexType</returns> internal static Diagram CreateDiagramWithDefaultName(CommandProcessorContext cpc) { Debug.Assert(cpc != null, "The passed in CommandProcessorContext is null."); if (cpc != null) { var service = cpc.EditingContext.GetEFArtifactService(); var entityDesignArtifact = service.Artifact as EntityDesignArtifact; if (entityDesignArtifact == null || entityDesignArtifact.DesignerInfo == null || entityDesignArtifact.DesignerInfo.Diagrams == null) { throw new CannotLocateParentItemException(); } var diagramName = ModelHelper.GetUniqueNameWithNumber( typeof(Diagram), entityDesignArtifact.DesignerInfo.Diagrams, Resources.Model_DefaultDiagramName); // go create it var cp = new CommandProcessor(cpc); var cmd = new CreateDiagramCommand(diagramName, entityDesignArtifact.DesignerInfo.Diagrams); cp.EnqueueCommand(cmd); cp.Invoke(); return cmd.Diagram; } return null; }
/// <summary> /// The method will do the following: /// - Creates a complex property with specified typeName in the entity-type. /// - The complex property will be inserted in the specified position. /// - Set the property's facet values. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the new property</param> /// <param name="entityType">The entity to create this property in</param> /// <param name="typeName">The complex property name.</param> /// <param name="concurrencyMode">The property concurrencyMode facet value.</param> /// <param name="getterAccessModifier">The property getterAccessModifier facet value.</param> /// <param name="setterAccessModifier">The property setterAccessModifier facet value.</param> /// <param name="insertPosition">Information where the property should be inserted to. If the parameter is null, the property will be placed as the last property of the entity.</param> /// <returns></returns> internal static ComplexConceptualProperty CreateComplexProperty( CommandProcessorContext cpc, string name, EntityType entityType, string typeName, string concurrencyMode, string getterAccessModifier, string setterAccessModifier, InsertPropertyPosition insertPosition) { var cmd = new CreateComplexPropertyCommand(name, entityType, typeName, insertPosition); cmd.PostInvokeEvent += (o, eventsArgs) => { var complexProperty = cmd.Property; Debug.Assert(complexProperty != null, "We didn't get good property out of the command"); if (complexProperty != null) { // set ComplexProperty attributes if (!String.IsNullOrEmpty(concurrencyMode)) { complexProperty.ConcurrencyMode.Value = concurrencyMode; } if (!String.IsNullOrEmpty(getterAccessModifier)) { complexProperty.Getter.Value = getterAccessModifier; } if (!String.IsNullOrEmpty(setterAccessModifier)) { complexProperty.Setter.Value = setterAccessModifier; } } }; var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); return(cmd.Property); }
/// <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 static void StaticInvoke(CommandProcessorContext cpc, EntityTypeShape entityTypeShape, Guid domainPropertyId) { var viewModel = entityTypeShape.GetRootViewModel(); Debug.Assert(viewModel != null, "Unable to find root view model from entity type shape:" + entityTypeShape.AccessibleName); if (viewModel != null) { var modelEntityShape = viewModel.ModelXRef.GetExisting(entityTypeShape) as Model.Designer.EntityTypeShape; // If ModelXRef does not contain about model EntityTypeShape,try to get the information through DSL Model Element if (modelEntityShape == null) { var modelDiagram = viewModel.ModelXRef.GetExisting(viewModel.GetDiagram()) as Diagram; var entityType = viewModel.ModelXRef.GetExisting(entityTypeShape.ModelElement) as EntityType; Debug.Assert(modelDiagram != null, "Why Escher Diagram is null?"); Debug.Assert(entityType != null, "Why there is no XRef between Escher EntityType and DSL EntityT?"); if (modelDiagram != null && entityType != null) { modelEntityShape = entityType.GetAntiDependenciesOfType<Model.Designer.EntityTypeShape>() .FirstOrDefault(ets => ets.Diagram.Id == modelDiagram.Id.Value); } if (modelEntityShape != null) { viewModel.ModelXRef.Add(modelEntityShape, entityTypeShape, cpc.EditingContext); } } // if modelentityshape is still null, create one if (modelEntityShape == null) { EntityTypeShapeAdd.StaticInvoke(cpc, entityTypeShape); modelEntityShape = viewModel.ModelXRef.GetExisting(entityTypeShape) as Model.Designer.EntityTypeShape; } Debug.Assert(modelEntityShape != null); if (modelEntityShape != null) { if (domainPropertyId == NodeShape.AbsoluteBoundsDomainPropertyId) { var cp = new CommandProcessor(cpc); cp.EnqueueCommand( new UpdateDefaultableValueCommand<double>(modelEntityShape.PointX, entityTypeShape.AbsoluteBounds.X)); cp.EnqueueCommand( new UpdateDefaultableValueCommand<double>(modelEntityShape.PointY, entityTypeShape.AbsoluteBounds.Y)); cp.EnqueueCommand( new UpdateDefaultableValueCommand<double>(modelEntityShape.Width, entityTypeShape.AbsoluteBounds.Width)); cp.Invoke(); } else if (domainPropertyId == NodeShape.IsExpandedDomainPropertyId) { var cmd = new UpdateDefaultableValueCommand<bool>(modelEntityShape.IsExpanded, entityTypeShape.IsExpanded); CommandProcessor.InvokeSingleCommand(cpc, cmd); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // first create new ComplexType _createdComplexType = CreateComplexTypeCommand.CreateComplexTypeWithDefaultName(cpc); // add a copy of Entity properties to the ComplexType var copyCmd = new CopyPropertiesCommand(new PropertiesClipboardFormat(_properties), _createdComplexType); var propertyName = ModelHelper.GetUniqueConceptualPropertyName( ComplexConceptualProperty.DefaultComplexPropertyName, _entityType); // add a new Property of created ComplexType to the Entity var createCPCmd = new CreateComplexPropertyCommand(propertyName, _entityType, _createdComplexType); var cp = new CommandProcessor(cpc, copyCmd, createCPCmd); cp.Invoke(); _createdComplexProperty = createCPCmd.Property; // preserve mappings foreach (var property in _properties) { if (property is ComplexConceptualProperty) { var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value) as ComplexConceptualProperty; Debug.Assert(createdComplexTypeProperty != null, "Copied complex property not found"); if (createdComplexTypeProperty != null) { foreach (var complexPropertyMapping in property.GetAntiDependenciesOfType <ComplexProperty>()) { PreserveComplexPropertyMapping(cpc, complexPropertyMapping, createdComplexTypeProperty); } foreach (var fcp in property.GetAntiDependenciesOfType <FunctionComplexProperty>()) { PreserveFunctionComplexPropertyMapping(cpc, fcp, createdComplexTypeProperty); } } } else { var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value); Debug.Assert(createdComplexTypeProperty != null, "Copied property not found"); if (createdComplexTypeProperty != null) { // update EntityTypeMappings foreach (var scalarPropertyMapping in property.GetAntiDependenciesOfType <ScalarProperty>()) { PreserveScalarPropertyMapping(cpc, scalarPropertyMapping, createdComplexTypeProperty); } // update ModificationFunctionMappings foreach (var fsp in property.GetAntiDependenciesOfType <FunctionScalarProperty>()) { PreserveFunctionScalarPropertyMapping(cpc, fsp, createdComplexTypeProperty); } } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // first create new ComplexType _createdComplexType = CreateComplexTypeCommand.CreateComplexTypeWithDefaultName(cpc); // add a copy of Entity properties to the ComplexType var copyCmd = new CopyPropertiesCommand(new PropertiesClipboardFormat(_properties), _createdComplexType); var propertyName = ModelHelper.GetUniqueConceptualPropertyName( ComplexConceptualProperty.DefaultComplexPropertyName, _entityType); // add a new Property of created ComplexType to the Entity var createCPCmd = new CreateComplexPropertyCommand(propertyName, _entityType, _createdComplexType); var cp = new CommandProcessor(cpc, copyCmd, createCPCmd); cp.Invoke(); _createdComplexProperty = createCPCmd.Property; // preserve mappings foreach (var property in _properties) { if (property is ComplexConceptualProperty) { var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value) as ComplexConceptualProperty; Debug.Assert(createdComplexTypeProperty != null, "Copied complex property not found"); if (createdComplexTypeProperty != null) { foreach (var complexPropertyMapping in property.GetAntiDependenciesOfType<ComplexProperty>()) { PreserveComplexPropertyMapping(cpc, complexPropertyMapping, createdComplexTypeProperty); } foreach (var fcp in property.GetAntiDependenciesOfType<FunctionComplexProperty>()) { PreserveFunctionComplexPropertyMapping(cpc, fcp, createdComplexTypeProperty); } } } else { var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value); Debug.Assert(createdComplexTypeProperty != null, "Copied property not found"); if (createdComplexTypeProperty != null) { // update EntityTypeMappings foreach (var scalarPropertyMapping in property.GetAntiDependenciesOfType<ScalarProperty>()) { PreserveScalarPropertyMapping(cpc, scalarPropertyMapping, createdComplexTypeProperty); } // update ModificationFunctionMappings foreach (var fsp in property.GetAntiDependenciesOfType<FunctionScalarProperty>()) { PreserveFunctionScalarPropertyMapping(cpc, fsp, createdComplexTypeProperty); } } } } }
/// <summary> /// Creates scalar property with a default, unique name and passed type /// </summary> /// <param name="cpc"></param> /// <param name="parentComplexType">parent for new property</param> /// <param name="type">type for new property</param> /// <returns></returns> internal static Property CreateDefaultProperty(CommandProcessorContext cpc, ComplexType parentComplexType, string type) { var name = ModelHelper.GetUniqueName(typeof(ConceptualProperty), parentComplexType, Property.DefaultPropertyName); var cmd = new CreateComplexTypePropertyCommand(name, parentComplexType, type, false); var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); return(cmd.Property); }
internal static Association CreateAssociationAndAssociationSetWithDefaultNames( CommandProcessorContext cpc, ConceptualEntityType end1Entity, ConceptualEntityType end2Entity) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the association to var model = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } // Should have discovered the association name through the behavior service. Going back to default var associationName = ModelHelper.GetUniqueName( typeof(Association), model, end1Entity.LocalName.Value + end2Entity.LocalName.Value); // pluralization service is based on English only for Dev10 IPluralizationService pluralizationService = null; var pluralize = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool( OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeEnablePluralization, OptionsDesignerInfo.EnablePluralizationDefault, artifact); if (pluralize) { pluralizationService = DependencyResolver.GetService <IPluralizationService>(); } var end1Multiplicity = ModelConstants.Multiplicity_One; var end2Multiplicity = ModelConstants.Multiplicity_Many; var proposedEnd1NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end2Entity.LocalName.Value, end2Multiplicity); var end1NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName(proposedEnd1NavPropName, end1Entity); var proposedEnd2NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end1Entity.LocalName.Value, end1Multiplicity); var end2NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName( proposedEnd2NavPropName, end2Entity, new HashSet <string> { end1NavigationPropertyName }); var cac = new CreateConceptualAssociationCommand( associationName, end1Entity, end1Multiplicity, end1NavigationPropertyName, end2Entity, end2Multiplicity, end2NavigationPropertyName, false, // uniquify names false); // create foreign key properties var cp = new CommandProcessor(cpc, cac); cp.Invoke(); return(cac.CreatedAssociation); }
/// <summary> /// Creates a property in the passed in entity of the default Type (non-nullable String). /// 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 property</param> /// <param name="entityType">The entity to create this property in</param> /// <returns>The new Property</returns> internal static Property CreateDefaultProperty(CommandProcessorContext cpc, string name, EntityType entityType) { var cpcd = new CreatePropertyCommand( name, entityType, ModelConstants.DefaultPropertyType, ModelConstants.DefaultPropertyNullability); cpcd._createWithDefaultName = true; var cp = new CommandProcessor(cpc, cpcd); cp.Invoke(); return(cpcd.CreatedProperty); }
internal override void Invoke(CommandProcessorContext cpc) { var viewModel = _entityType.GetRootViewModel(); Debug.Assert(viewModel != null, "Unable to find root view model from entity type: " + _entityType.Name); if (viewModel != null) { var entityType = viewModel.ModelXRef.GetExisting(_entityType) as Model.Entity.EntityType; Debug.Assert(entityType != null); Command c = new EntityDesignRenameCommand(entityType, _entityType.Name, true); var cp = new CommandProcessor(cpc, c); cp.Invoke(); } }
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 Model.Entity.Property; Debug.Assert(property != null); Command c = new EntityDesignRenameCommand(property, _property.Name, true); var cp = new CommandProcessor(cpc, c); cp.Invoke(); } }
/// <summary> /// This helper function creates a new entity in the conceptual model that is derived from the /// passed in entity. /// 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, derived entity</param> /// <param name="baseType">The entity that this new type should derive from</param> /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param> /// <returns>The new EntityType</returns> internal static ConceptualEntityType CreateDerivedEntityType( CommandProcessorContext cpc, string name, ConceptualEntityType baseType, bool uniquifyName) { var cet = new CreateEntityTypeCommand(name, uniquifyName); var inh = new CreateInheritanceCommand(cet, baseType); var cp = new CommandProcessor(cpc, cet, inh); cp.Invoke(); var derivedType = cet.EntityType as ConceptualEntityType; Debug.Assert(derivedType != null, "EntityType is not ConceptualEntityType"); return(derivedType); }
/// <summary> /// Creates a complex property in the passed in entity of the first ComplexType in the model ("Undefined" if there isn't one). /// 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 committed. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the new property</param> /// <param name="entityType">The entity to create this property in</param> /// <returns>The new Complex Property</returns> internal static ComplexConceptualProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, EntityType entityType) { var model = entityType.EntityModel as ConceptualEntityModel; ComplexType type = null; foreach (var complexType in model.ComplexTypes()) { type = complexType; break; } var cpcd = new CreateComplexPropertyCommand(name, entityType, type); var cp = new CommandProcessor(cpc, cpcd); cp.Invoke(); return(cpcd.Property); }
/// <summary> /// Creates a new property in the passed in storage entity and optionally sets additional /// facets on the property. /// 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 property</param> /// <param name="entityType">Must be a storage entity</param> /// <param name="type">The type to use for this property (cannot be empty)</param> /// <param name="nullable">Flag whether the property is nullable or not</param> /// <param name="theDefault">Optional: the default value for this property</param> /// <param name="maxLength">Optional facet</param> /// <param name="fixedLength">Optional facet</param> /// <param name="precision">Optional facet</param> /// <param name="scale">Optional facet</param> /// <param name="unicode">Optional facet</param> /// <param name="collation">Optional facet</param> /// <param name="concurrencyMode">Optional: the concurrency mode for this property</param> /// <returns>The new Property</returns> internal static Property CreateStorageProperty( CommandProcessorContext cpc, string name, StorageEntityType entityType, string type, bool?nullable, StringOrNone theDefault, StringOrPrimitive <UInt32> maxLength, BoolOrNone fixedLength, StringOrPrimitive <UInt32> precision, StringOrPrimitive <UInt32> scale, BoolOrNone unicode, StringOrNone collation, string concurrencyMode) { CommandValidation.ValidateStorageEntityType(entityType); var cpcd = new CreatePropertyCommand(name, entityType, type, nullable); var ssp = new SetPropertyFacetsCommand( cpcd, theDefault, maxLength, fixedLength, precision, scale, unicode, collation, concurrencyMode); var cp = new CommandProcessor(cpc, cpcd, ssp); cp.Invoke(); return(cpcd.CreatedProperty); }
/// <summary> /// Creates a new property in the passed in conceptual entity and optionally sets additional /// facets on the property. /// 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 property</param> /// <param name="entityType">Must be a conceptual entity</param> /// <param name="type">The type to use for this property (cannot be empty)</param> /// <param name="nullable">Flag whether the property is nullable or not</param> /// <param name="theDefault">Optional: the default value for this property</param> /// <param name="concurrencyMode">Optional: the concurrency mode for this property</param> /// <param name="getterAccessModifier">Optional: Get access modifier.</param> /// <param name="setterAccessModifier">Optional: Set access modifier.</param> /// <returns>The new Property</returns> internal static Property CreateConceptualProperty( CommandProcessorContext cpc, string name, ConceptualEntityType entityType, string type, bool?nullable, StringOrNone theDefault, string concurrencyMode, string getterAccessModifier, string setterAccessModifier, StringOrPrimitive <UInt32> maxLength, bool?fixedLength, StringOrPrimitive <UInt32> precision, StringOrPrimitive <UInt32> scale, bool?unicode, StringOrNone collation, string storeGeneratedPattern, InsertPropertyPosition insertPosition) { CommandValidation.ValidateConceptualEntityType(entityType); var cpcd = new CreatePropertyCommand(name, entityType, type, nullable, insertPosition); var scp = new SetConceptualPropertyFacetsCommand( cpcd, theDefault, concurrencyMode, getterAccessModifier, setterAccessModifier, maxLength, DefaultableValueBoolOrNone.GetFromNullableBool(fixedLength), precision, scale, DefaultableValueBoolOrNone.GetFromNullableBool(unicode), collation); var scpac = new SetConceptualPropertyAnnotationsCommand(cpcd, storeGeneratedPattern); var cp = new CommandProcessor(cpc, cpcd, scp, scpac); cp.Invoke(); return(cpcd.CreatedProperty); }
internal static NavigationProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, ConceptualEntityType entity) { if (cpc == null) { throw new ArgumentNullException("cpc"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (entity == null) { throw new ArgumentNullException("entity"); } var cpcd = new CreateNavigationPropertyCommand(name, entity, null, null, null); var cp = new CommandProcessor(cpc, cpcd); cp.Invoke(); return cpcd.NavigationProperty; }
internal static bool SetBaseEntityType( CommandProcessorContext cpc, ConceptualEntityType derivedEntity, ConceptualEntityType baseEntity) { if (ModelHelper.CheckForCircularInheritance(derivedEntity, baseEntity)) { var message = String.Format( CultureInfo.CurrentCulture, Resources.Error_CircularInheritanceAborted, derivedEntity.LocalName.Value, baseEntity.LocalName.Value); VsUtils.ShowErrorDialog(message); return false; } var cp = new CommandProcessor(cpc); if (derivedEntity.BaseType.Target != null) { // CreateInheritanceCommand works only for entities that don't have base type set // so we need to remove base type first in this case cp.EnqueueCommand(new DeleteInheritanceCommand(derivedEntity)); } if (baseEntity != null) { // in case the user has chosen "(None)" then we just want to delete the existing one cp.EnqueueCommand(new CreateInheritanceCommand(derivedEntity, baseEntity)); } // a quick check to be sure Debug.Assert(cp.CommandCount > 0, "Why didn't we enqueue at least one command?"); if (cp.CommandCount > 0) { cp.Invoke(); } return true; }
/// <summary> /// This helper function will create a complex type using default name. /// 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 committed. /// </summary> /// <param name="cpc"></param> /// <returns>The new ComplexType</returns> internal static ComplexType CreateComplexTypeWithDefaultName(CommandProcessorContext cpc) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the complex type to var model = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } var complexTypeName = ModelHelper.GetUniqueNameWithNumber(typeof(ComplexType), model, Resources.Model_DefaultComplexTypeName); // go create it var cp = new CommandProcessor(cpc); var cmd = new CreateComplexTypeCommand(complexTypeName, false); cp.EnqueueCommand(cmd); cp.Invoke(); return(cmd.ComplexType); }
internal static NavigationProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, ConceptualEntityType entity) { if (cpc == null) { throw new ArgumentNullException("cpc"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (entity == null) { throw new ArgumentNullException("entity"); } var cpcd = new CreateNavigationPropertyCommand(name, entity, null, null, null); var cp = new CommandProcessor(cpc, cpcd); cp.Invoke(); return(cpcd.NavigationProperty); }
/// <summary> /// Creates a new EntityTypeMapping in the existing EntitySetMapping /// based on another EntityTypeMapping (etmToClone) in a different artifact. /// All the other parameters are presumed to already exist in the same artifact /// as the EntitySetMapping. /// </summary> internal static EntityTypeMapping CloneEntityTypeMapping( CommandProcessorContext cpc, EntityTypeMapping etmToClone, EntitySetMapping existingEntitySetMapping, ConceptualEntityType existingEntityType, EntityTypeMappingKind kind) { var createETM = new CreateEntityTypeMappingCommand(existingEntitySetMapping, existingEntityType, kind); var cp = new CommandProcessor(cpc, createETM); cp.Invoke(); var etm = createETM.EntityTypeMapping; foreach (var mappingFragment in etmToClone.MappingFragments()) { var sesToClone = mappingFragment.StoreEntitySet.Target as StorageEntitySet; var ses = existingEntitySetMapping.EntityContainerMapping.Artifact. StorageModel().FirstEntityContainer.GetFirstNamedChildByLocalName(sesToClone.LocalName.Value) as StorageEntitySet; CreateMappingFragmentCommand.CloneMappingFragment(cpc, mappingFragment, etm, ses); } return(etm); }
/// <summary> /// This helper function creates a new entity in the conceptual model that is derived from the /// passed in entity. /// 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, derived entity</param> /// <param name="baseType">The entity that this new type should derive from</param> /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param> /// <returns>The new EntityType</returns> internal static ConceptualEntityType CreateDerivedEntityType( CommandProcessorContext cpc, string name, ConceptualEntityType baseType, bool uniquifyName) { var cet = new CreateEntityTypeCommand(name, uniquifyName); var inh = new CreateInheritanceCommand(cet, baseType); var cp = new CommandProcessor(cpc, cet, inh); cp.Invoke(); var derivedType = cet.EntityType as ConceptualEntityType; Debug.Assert(derivedType != null, "EntityType is not ConceptualEntityType"); return derivedType; }
/// <summary> /// Creates complex property with a default,unique name and passed complex type /// </summary> /// <param name="cpc"></param> /// <param name="parentComplexType">parent for new property</param> /// <param name="type">type for new property</param> /// <returns></returns> internal static Property CreateDefaultProperty(CommandProcessorContext cpc, ComplexType parentComplexType, ComplexType type) { var name = ModelHelper.GetUniqueName( typeof(ConceptualProperty), parentComplexType, ComplexConceptualProperty.DefaultComplexPropertyName); var cmd = new CreateComplexTypePropertyCommand(name, parentComplexType, type, false); var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); return cmd.Property; }
internal void watermarkLabel_LinkClickedDeleteAssociation(object sender, LinkLabelLinkClickedEventArgs e) { var association = _toolWindow.GetAssociationFromLastPrimarySelection(); if (association == null) { Debug.Fail("association is null"); return; } var associationSetMappings = association.AssociationSet.GetAntiDependenciesOfType<AssociationSetMapping>(); Debug.Assert(_hostContext == _toolWindow.Context, "this.HostContext != to window.Context!"); if (HostContext == null) { Debug.Fail("Host context is null"); } else { var cpc = new CommandProcessorContext( _hostContext, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_DeleteAssociationSetMapping); var cp = new CommandProcessor(cpc); foreach (var associationSetMapping in associationSetMappings) { cp.EnqueueCommand(new DeleteEFElementCommand(associationSetMapping)); } if (cp.CommandCount > 0) { cp.Invoke(); } } // reset watermark text to account for the deleted ASM. if (_toolWindow.CanEditMappingsForAssociation(association, false)) { _toolWindow.SetUpAssociationDisplay(); } }
/// <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> /// This helper function will create a complex type using default name. /// 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> /// <returns>The new ComplexType</returns> internal static ComplexType CreateComplexTypeWithDefaultName(CommandProcessorContext cpc) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the complex type to var model = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } var complexTypeName = ModelHelper.GetUniqueNameWithNumber(typeof(ComplexType), model, Resources.Model_DefaultComplexTypeName); // go create it var cp = new CommandProcessor(cpc); var cmd = new CreateComplexTypeCommand(complexTypeName, false); cp.EnqueueCommand(cmd); cp.Invoke(); return cmd.ComplexType; }
public override void OnDoubleClick(DiagramPointEventArgs e) { var association = ModelElement; if (association != null) { var diagram = Diagram as EntityDesignerDiagram; if (diagram != null) { var ec = diagram.GetModel().EditingContext; var xref = ModelToDesignerModelXRef.GetModelToDesignerModelXRef(ec); var modelAssociation = xref.GetExisting(association) as Model.Entity.Association; Debug.Assert(modelAssociation != null, "couldn't find model association for connector"); if (modelAssociation != null) { var commands = ReferentialConstraintDialog.LaunchReferentialConstraintDialog(modelAssociation); var cpc = new CommandProcessorContext( ec, EfiTransactionOriginator.EntityDesignerOriginatorId, Resources.Tx_ReferentialContraint); var cp = new CommandProcessor(cpc); foreach (var c in commands) { cp.EnqueueCommand(c); } cp.Invoke(); } } } }
public void FunctionImportReturnComplexType() { UITestRunner.Execute(TestContext.TestName, () => { const string testName = "UndoRedo.FunctionImportReturnComplexType"; ExecuteUndoRedoTest( testName, "NorthwindModel.edmx", (commandProcessorContext, artifact) => { var dte = VsIdeTestHostContext.Dte; var commandProcessor = new CommandProcessor(commandProcessorContext); var createComplexTypeCmd = new CreateComplexTypeCommand("Sales_by_year_result", true); commandProcessor.EnqueueCommand(createComplexTypeCmd); commandProcessor.EnqueueCommand( new CreateComplexTypePropertyCommand("Column1", createComplexTypeCmd, "Int32", false)); commandProcessor.EnqueueCommand( new CreateFunctionImportCommand( artifact.GetFreshConceptualEntityContainer("NorthwindEntities"), artifact.GetFreshStorageFunction("Sales_by_Year"), "myfunctionimport", createComplexTypeCmd)); commandProcessor.Invoke(); Assert.IsNotNull(artifact.GetFreshComplexType("Sales_by_year_result")); Assert.IsNotNull(artifact.GetFreshComplexType("Sales_by_year_result")); Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport")); Assert.AreEqual( "Collection(NorthwindModel.Sales_by_year_result)", ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("myfunctionimport").ReturnType) .RefName); //Undo Redo Create FunctionImport dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNull(artifact.GetFreshComplexType("Sales_by_year_result")); Assert.IsNull(artifact.GetFreshFunctionImport("myfunctionimport")); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.IsNotNull(artifact.GetFreshComplexType("Sales_by_year_result")); Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport")); Assert.AreEqual( "Collection(NorthwindModel.Sales_by_year_result)", ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("myfunctionimport").ReturnType) .RefName); CommandProcessor.InvokeSingleCommand( commandProcessorContext, new CreateFunctionImportCommand( artifact.GetFreshConceptualEntityContainer("NorthwindEntities"), artifact.GetFreshStorageFunction("GetFreightCost"), "myfunctionimport2", "String")); Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport2")); Assert.AreEqual( "Collection(String)", ((DefaultableValue<String>)artifact.GetFreshFunctionImport("myfunctionimport2").ReturnType).Value); createComplexTypeCmd = new CreateComplexTypeCommand("GetFreightCost_result", true); commandProcessor.EnqueueCommand(createComplexTypeCmd); commandProcessor.EnqueueCommand( new ChangeFunctionImportCommand( artifact.GetFreshConceptualEntityContainer("NorthwindEntities"), artifact.GetFreshFunctionImport("myfunctionimport2"), artifact.GetFreshStorageFunction("GetFreightCost"), "test123", /* isComposable */ BoolOrNone.FalseValue, createComplexTypeCmd)); commandProcessor.Invoke(); Assert.IsNull(artifact.GetFreshFunctionImport("myfunctionimport2")); Assert.IsNotNull(artifact.GetFreshFunctionImport("test123")); Assert.AreEqual( "Collection(NorthwindModel.GetFreightCost_result)", ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("test123").ReturnType).RefName); Assert.IsNotNull(artifact.GetFreshComplexType("GetFreightCost_result")); // Undo redo "Change FunctionImport" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNull(artifact.GetFreshFunctionImport("test123")); Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport2")); Assert.AreEqual( "Collection(String)", ((DefaultableValue<String>)artifact.GetFreshFunctionImport("myfunctionimport2").ReturnType).Value); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.IsNull(artifact.GetFreshFunctionImport("myfunctionimport2")); Assert.IsNotNull(artifact.GetFreshFunctionImport("test123")); Assert.AreEqual( "Collection(NorthwindModel.GetFreightCost_result)", ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("test123").ReturnType).RefName); Assert.IsNotNull(artifact.GetFreshComplexType("GetFreightCost_result")); }); }); }
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); } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert(cpc != null, "InvokeInternal is called when ExitingFunctionScalarProperty is null."); // safety check, this should never be hit if (_existingFunctionScalarProperty == null) { throw new InvalidOperationException("InvokeInternal is called when ExitingFunctionScalarProperty is null."); } if (_propChain == null && _pointingNavProp == null && _param == null && _version != null) { // setting new version only if (string.Compare(_existingFunctionScalarProperty.Version.Value, _version, StringComparison.CurrentCulture) != 0) { var mfAncestor = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction; Debug.Assert( mfAncestor != null, "Bad attempt to set version on FunctionScalarProperty which does not have a ModificationFunction ancestor"); if (mfAncestor != null) { Debug.Assert( mfAncestor.FunctionType == ModificationFunctionType.Update, "Bad attempt to set version on FunctionScalarProperty which has a ModificationFunction ancestor whose FunctionType is " + mfAncestor.FunctionType.ToString() + ". Should be " + ModificationFunctionType.Update.ToString()); if (mfAncestor.FunctionType == ModificationFunctionType.Update) { _existingFunctionScalarProperty.Version.Value = _version; } } } _updatedFunctionScalarProperty = _existingFunctionScalarProperty; return; } // if not just setting version then need to delete and re-create FunctionScalarProperty // to allow for changes in properties chain // where nulls have been passed in, use existing values (except for _pointingNavProp where null // indicates "use no NavProp for the new property") var mf = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction; Debug.Assert(mf != null, "Bad attempt to change FunctionScalarProperty which does not have a ModificationFunction ancestor"); if (mf == null) { return; } var propChain = (_propChain != null ? _propChain : _existingFunctionScalarProperty.GetMappedPropertiesList()); var parameter = (_param != null ? _param : _existingFunctionScalarProperty.ParameterName.Target); var version = (_version != null ? _version : _existingFunctionScalarProperty.Version.Value); // now construct delete command for existing FunctionScalarProperty followed by create with new properties var cmd1 = _existingFunctionScalarProperty.GetDeleteCommand(); var cmd2 = new CreateFunctionScalarPropertyTreeCommand(mf, propChain, _pointingNavProp, parameter, version); cmd2.PostInvokeEvent += (o, eventsArgs) => { _updatedFunctionScalarProperty = cmd2.FunctionScalarProperty; Debug.Assert( _updatedFunctionScalarProperty != null, "CreateFunctionScalarPropertyTreeCommand should not result in null FunctionScalarProperty"); }; var cp = new CommandProcessor(cpc, cmd1, cmd2); try { cp.Invoke(); } finally { _updatedFunctionScalarProperty = null; } }
public void Mapping_General_Blank() { UITestRunner.Execute(TestContext.TestName, () => { const string typePrefix = "Mapping_General_Blank"; const string testName = "UndoRedo." + typePrefix; ExecuteUndoRedoTest( testName, "BlankModel.edmx", (commandProcessorContext, artifact) => { const string entityType1Name = typePrefix + "_EntityType1"; const string entityType2Name = typePrefix + "_EntityType2"; const string entitySetName = typePrefix + "_EntitySet"; var dte = VsIdeTestHostContext.Dte; CreateDefaultEntityType(commandProcessorContext, entityType1Name, entitySetName); CreateEntityTypeCommand.CreateConceptualEntityTypeAndEntitySetAndProperty( commandProcessorContext, entityType2Name, entitySetName, /*createKeyProperty*/ false, null, null, null, /*uniquifyNames*/ true); new CommandProcessor( commandProcessorContext, new CreateInheritanceCommand( artifact.GetFreshConceptualEntity(entityType2Name), artifact.GetFreshConceptualEntity(entityType1Name))).Invoke(); // CREATE TWO ENTITY TYPE MAPPINGS WITHIN THE SAME ENTITY SET MAPPING var commandProcessor = new CommandProcessor(commandProcessorContext); commandProcessor.EnqueueCommand( new CreateEntityTypeMappingCommand(artifact.GetFreshConceptualEntity(entityType1Name))); commandProcessor.EnqueueCommand( new CreateEntityTypeMappingCommand(artifact.GetFreshConceptualEntity(entityType2Name))); commandProcessor.Invoke(); Assert.AreEqual(2, artifact.GetFreshEntitySetMapping(entitySetName).EntityTypeMappings().Count); // Undo redo "Create two EntityTypeMappings within same EntitySetMapping" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNull(artifact.GetFreshEntitySetMapping(entitySetName)); Assert.IsNotNull(artifact.GetFreshConceptualEntity(entityType1Name)); Assert.IsNotNull(artifact.GetFreshConceptualEntity(entityType2Name)); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.AreEqual(2, artifact.GetFreshEntitySetMapping(entitySetName).EntityTypeMappings().Count); }); }); }
/// <summary> /// Invokes a single command against the CommandProcessor. /// </summary> internal static void InvokeSingleCommand(CommandProcessorContext cpc, Command cmd) { var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); }
internal void ChangeFunctionScalarProperty(EditingContext context, List<Property> newPropertiesChain) { if (ScalarProperty == null) { // if we don't have a scalar property, there is nothing to set this into; // create the scalar property first throw new InvalidOperationException(); } else { // is the propertiesChain different from what we have already? var propertiesChain = ScalarProperty.GetMappedPropertiesList(); var changeNeeded = false; 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 no change needed yet, check NavProp as well if (changeNeeded == false) { // if this property is pointed to by a navigation property, then check if the // new navigation property is different from the old one if (ScalarProperty.AssociationEnd != null) { var currentNavProp = ModelHelper.FindNavigationPropertyForFunctionScalarProperty(ScalarProperty); // currentNavProp can be null if the NavProp has been deleted changeNeeded = (currentNavProp == null ? true : (currentNavProp != _pointingNavProperty)); } else { // the previous property was not pointed to by a navigation property but the new one is if (_pointingNavProperty != null) { changeNeeded = true; } } } } if (changeNeeded) { // delete old and create new FunctionScalarProperty in one transaction - this takes care of // removing any old ComplexProperty or AssociationEnd parent nodes as necessary var cpc = new CommandProcessorContext( context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_ChangeScalarProperty); var version = (ScalarProperty.Version == null ? null : ScalarProperty.Version.Value); // Version is used only for Update ModificationFunctions var cmd = new ChangeFunctionScalarPropertyCommand( ScalarProperty, newPropertiesChain, _pointingNavProperty, StoreParameter, version); cmd.PostInvokeEvent += (o, eventsArgs) => { var fsp = cmd.FunctionScalarProperty; Debug.Assert(fsp != null, "ChangeFunctionScalarPropertyCommand failed to create a FunctionScalarProperty"); ModelItem = fsp; }; var cp = new CommandProcessor(cpc, cmd); try { cp.Invoke(); } catch { ModelItem = null; throw; } } } }
/// <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; }
// <summary> // The mapping view model contains a MappingEndScalarProperty for every key in each end. The user can clear out the // underlying scalar property, but that doesn't remove or add the MappingEndScalarProperty. 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 override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem) { Debug.Assert(underlyingModelItem != null, "The underlyingModelItem cannot be null"); var tableColumn = underlyingModelItem as Property; 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(tableColumn != null, "The tableColumn cannot be null."); if (tableColumn == null) { return; } Debug.Assert(tableColumn.EntityType.EntityModel.IsCSDL == false, "tableColumn must be a Store-side Property"); Context = context; // find the c-side property based on the passed in name var entityProperty = MappingAssociationSetEnd.ConceptualEntityType.GetFirstNamedChildByLocalName(Property) as Property; if (entityProperty == null) { // they might be trying to map a key from the base class EntityType topMostBaseType = MappingAssociationSetEnd.ConceptualEntityType.ResolvableTopMostBaseType; entityProperty = topMostBaseType.GetFirstNamedChildByLocalName(Property) as Property; } Debug.Assert(entityProperty != null, "Failed looking up entity property for ScalarProperty."); if (entityProperty == null) { return; } // create our context if we don't have one if (cpc == null) { cpc = new CommandProcessorContext( Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateScalarProperty); } // create the right command CreateEndScalarPropertyCommand cmd = null; var end = MappingAssociationSetEnd.AssociationSetEnd.EndProperty; if (end == null) { // we don't have an end yet, this version will create an end as well as the scalar property cmd = new CreateEndScalarPropertyCommand( MappingAssociationSet.AssociationSet.AssociationSetMapping, MappingAssociationSetEnd.AssociationSetEnd, entityProperty, tableColumn); } else { cmd = new CreateEndScalarPropertyCommand(end, entityProperty, tableColumn); } // set up our post event to fix up the view model cmd.PostInvokeEvent += (o, eventArgs) => { var sp = cmd.ScalarProperty; Debug.Assert(sp != null, "cmd failed to generate 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 key in the entity) ModelItem = sp; }; try { // now make the change var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); } catch { ModelItem = null; throw; } }
internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem) { Debug.Assert(context != null, "The context argument cannot be null"); Debug.Assert(StorageEntityType == null, "Don't call this method if we already have a ModelItem"); Debug.Assert(MappingConceptualEntityType.ConceptualEntityType != null, "The parent item isn't set up correctly"); Debug.Assert(underlyingModelItem != null, "The underlyingModelItem cannot be null"); var storeEntityType = underlyingModelItem as EntityType; Debug.Assert( storeEntityType != null, "underlyingModelItem must be of type EntityType, actual type = " + underlyingModelItem.GetType().FullName); Debug.Assert(storeEntityType.EntityModel.IsCSDL == false, "The storageEntityType must not be a CSDL EntityType"); Context = context; ColumnMappings.Context = context; // create a context if we weren't passed one if (cpc == null) { cpc = new CommandProcessorContext( Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateMappingFragment); } // create the MappingFragment - if we already have a default EntityTypeMapping then just add // the MappingFragment to that mapping, otherwise if we already have an IsTypeOf // EntityTypeMapping then add the MappingFragment to that, otherwise create an IsTypeOf // EntityTypeMapping and add the MappingFragment to that var cet = MappingConceptualEntityType.ConceptualEntityType; var defaultEtm = ModelHelper.FindEntityTypeMapping(cpc, cet, EntityTypeMappingKind.Default, false); var etmKind = (defaultEtm == null ? EntityTypeMappingKind.IsTypeOf : EntityTypeMappingKind.Default); var cmd = new CreateMappingFragmentCommand(cet, storeEntityType, etmKind); // add post-invoke event to fix up our view model cmd.PostInvokeEvent += (o, eventsArgs) => { // fix up our view model ModelItem = storeEntityType; Parent.AddChild(this); // assign the table to our container node as well ColumnMappings.ModelItem = storeEntityType; // now try and do some match ups between the entity and the table var mappingStrategy = ModelHelper.DetermineCurrentInheritanceStrategy(cet); var topMostBaseType = cet.ResolvableTopMostBaseType; foreach (var child in ColumnMappings.Children) { var msp = child as MappingScalarProperty; if (msp != null) { List<Property> properties; if (ModelHelper.FindScalarPropertyPathByLocalName(cet, msp.ColumnName, out properties)) { msp.CreateModelItem(cpc, _context, properties); } else if (InheritanceMappingStrategy.TablePerType == mappingStrategy && ModelHelper.FindScalarPropertyPathByLocalName(topMostBaseType, msp.ColumnName, out properties)) { msp.CreateModelItem(cpc, _context, properties); } } } }; try { // now update the model var cp = new CommandProcessor(cpc); cp.EnqueueCommand(cmd); cp.Invoke(); } catch { ModelItem = null; ColumnMappings.ModelItem = null; Parent.RemoveChild(this); throw; } }
internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem) { Debug.Assert(context != null, "null context"); Debug.Assert(Function == null, "Don't call this method if we already have a ModelItem"); Debug.Assert(MappingFunctionEntityType.EntityType != null, "The parent item isn't set up correctly"); Debug.Assert(underlyingModelItem != null, "null underlyingModelItem"); var function = underlyingModelItem as Function; Debug.Assert( function != null, "underlyingModelItem must be of type Function, actual type = " + underlyingModelItem.GetType().FullName); Debug.Assert(!function.EntityModel.IsCSDL, "The function must be in the SSDL"); Context = context; // create a context if we weren't passed one if (cpc == null) { cpc = new CommandProcessorContext( Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateFunctionMapping); } // create the commands var cmd = new CreateFunctionMappingCommand(MappingFunctionEntityType.EntityType, function, null, _functionType); // set up our post event to fix up the view model cmd.PostInvokeEvent += (o, eventsArgs) => { var mf = cmd.ModificationFunction; Debug.Assert(mf != null, "null ModificationFunction"); // fix up our view model ModelItem = mf; // The parent item for the function mapping view model always has 3 children; insert, update and delete items. If there isn’t // a function mapped for any of these, then there is still a view model item since we want to display the ‘creator node’ text. // Calling this.Parent.AddChild(this) here would make the parent think it had a new child instead of updating the existing one - // so it is correct to _not_ call it here. }; var cmd2 = new DelegateCommand( () => { var mf = ModificationFunction; Debug.Assert( mf != null, "Null ModificationFunction when trying to create view-model dummy nodes in MappingModificationFunctionMapping.CreateModelItem()"); if (mf != null) { //set up _properties and _resultBindings here as they are dummy ViewModel nodes // (i.e. don't correspond to any underlying ModelItem) _properties = new MappingFunctionScalarProperties(context, mf, this); _resultBindings = new MappingResultBindings(context, mf, this); _properties.Parent.AddChild(_properties); _resultBindings.Parent.AddChild(_resultBindings); // now ensure _properties scalar properties children have been calculated // (this creates scalar properties with just the column info // since this ModificationFunction has not yet been mapped) _properties.LoadScalarProperties(); // now try and do some match ups between the function and the entity var mappedEntityType = MappingFunctionEntityType.EntityType as ConceptualEntityType; Debug.Assert( MappingFunctionEntityType.EntityType == null || mappedEntityType != null, "EntityType is not ConceptualEntityType"); if (mappedEntityType != null) { foreach (var mfsp in _properties.ScalarProperties) { // Try to do some auto-matching of the sproc's parameters to the EntityType's properties. // Search for a property in the mapped EntityType's inheritance hierarchy that matches the // parameter's name. First search this EntityType (both its scalar and complex properties), // then search its parents scalar and complex properties and so on up the hierarchy var propNameToSearchFor = mfsp.StoreParameter.LocalName.Value; var propList = new List<Property>(); var entityTypeToSearch = mappedEntityType; // reset this back to the mapped EntityType each time through the loop while (entityTypeToSearch != null && false == ModelHelper.FindScalarPropertyPathByLocalName( entityTypeToSearch, propNameToSearchFor, out propList)) { if (entityTypeToSearch.BaseType == null) { // safety code - this should not happen but will prevent an infinite loop if it does entityTypeToSearch = null; } else { entityTypeToSearch = entityTypeToSearch.BaseType.Target; } } // if propList is still empty that means we did not find a match - so leave the parameter unmapped if (propList.Count > 0) { mfsp.CreateModelItem(cpc, _context, propList); } } } } }); try { // now make the change var cp = new CommandProcessor(cpc); cp.EnqueueCommand(cmd); cp.EnqueueCommand(cmd2); cp.Invoke(); } catch { ModelItem = null; ClearChildren(); throw; } }
internal static bool UpdateEdmxAndEnvironment(ModelBuilderSettings settings) { var artifact = settings.Artifact as EntityDesignArtifact; if (artifact == null) { Debug.Fail("In trying to UpdateEdmxAndEnvironment(), No Artifact was found in the ModelBuilderSettings"); return false; } // Update the app. or web.config, register build providers etc ConfigFileHelper.UpdateConfig(settings); if (settings.SsdlStringReader != null && settings.MslStringReader != null) { // Create the XmlReaders for the ssdl and msl text var ssdlXmlReader = XmlReader.Create(settings.SsdlStringReader); var mslXmlReader = XmlReader.Create(settings.MslStringReader); // Set up our post event to clear out the error list var cmd = new ReplaceSsdlAndMslCommand(ssdlXmlReader, mslXmlReader); cmd.PostInvokeEvent += (o, e) => { var errorList = ErrorListHelper.GetSingleDocErrorList(e.CommandProcessorContext.Artifact.Uri); if (errorList != null) { errorList.Clear(); } }; // Update the model (all inside 1 transaction so we don't get multiple undo's/redo's) var editingContext = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(settings.Artifact.Uri); var cpc = new CommandProcessorContext( editingContext, EfiTransactionOriginator.GenerateDatabaseScriptFromModelId, Resources.Tx_GenerateDatabaseScriptFromModel); var cp = new CommandProcessor(cpc, cmd); var addUseLegacyProviderCommand = ModelHelper.CreateSetDesignerPropertyValueCommandFromArtifact( cpc.Artifact, OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeUseLegacyProvider, settings.UseLegacyProvider.ToString()); if (addUseLegacyProviderCommand != null) { cp.EnqueueCommand(addUseLegacyProviderCommand); } // When the user had a v2 edmx file (it can happen when creating a new empty model in a project targeting // .NET Framework 4 and the project does not have refereces to any of EF dlls) and selected EF6 in // the "create database from model" wizard we need to update the artifact to use v3 schemas otherwise // there will be a watermark saying that the edmx is not correct for the EF version and needs to be updated. // We only want to run this command if the version really changed to avoid the overhead. if (artifact.SchemaVersion != settings.TargetSchemaVersion) { cp.EnqueueCommand(new RetargetXmlNamespaceCommand(artifact, settings.TargetSchemaVersion)); } cp.Invoke(); } // First let's get the canonical file path since DTE needs this if (!string.IsNullOrEmpty(settings.DdlFileName) && settings.DdlStringReader != null) { var canonicalFilePath = string.Empty; try { var fi = new FileInfo(settings.DdlFileName); canonicalFilePath = fi.FullName; } catch (Exception e) { Debug.Fail( "We should have caught this exception '" + e.Message + "' immediately after the user clicked the 'Finish' button"); VsUtils.ShowErrorDialog( String.Format( CultureInfo.CurrentCulture, ModelWizard.Properties.Resources.ErrorCouldNotParseDdlFileName, settings.DdlFileName, e.Message)); return false; } // Output the DDL file, catch any Exceptions, display them, and revert // back to the last page of the wizard. try { OutputDdl(canonicalFilePath, settings.DdlStringReader); } catch (Exception e) { if (e.InnerException == null) { VsUtils.ShowErrorDialog( String.Format( CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdl, canonicalFilePath, e.Message)); } else { VsUtils.ShowErrorDialog( String.Format( CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdlWithInner, canonicalFilePath, e.Message, e.InnerException.Message)); } return false; } // Add DDL file to the project if it is inside the project string relativePath; if (VsUtils.TryGetRelativePathInProject(settings.Project, canonicalFilePath, out relativePath)) { AddDDLFileToProject(settings.Project, canonicalFilePath); } // Open the DDL file if it is not already open IVsUIHierarchy hier; uint itemId; IVsWindowFrame frame; if (VsShellUtilities.IsDocumentOpen( Services.ServiceProvider, canonicalFilePath, Guid.Empty, out hier, out itemId, out frame) == false) { VsShellUtilities.OpenDocument(Services.ServiceProvider, canonicalFilePath); } } return true; }
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; } } }
internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem) { Debug.Assert(context != null, "context must not be null"); Debug.Assert(Condition == 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(underlyingModelItem != null, "underlyingModelItem must not be null"); var tableColumn = underlyingModelItem as Property; Debug.Assert( tableColumn != null, "underlyingModelItem must be of type Property, actual type = " + underlyingModelItem.GetType().FullName); // store this off in case we have recover the condition later (if it moves to another ETM on us) _modelItemColumnName = tableColumn.LocalName.Value; Context = context; // local shortcuts EntityType entityType = MappingConceptualEntityType.ConceptualEntityType; // create a context if we weren't passed one if (cpc == null) { cpc = new CommandProcessorContext( Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateCondition); } // use empty string as a default condition value var cmd = new CreateFragmentConditionCommand(entityType, tableColumn, null, String.Empty); // set up our post event to fix up the view model cmd.PostInvokeEvent += (o, eventsArgs) => { var cond = cmd.CreatedCondition; Debug.Assert(cond != null, "cmd failed to create Condition"); // fix up our view model ModelItem = cond; Parent.AddChild(this); }; try { // now make the change var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); } catch { ModelItem = null; Parent.RemoveChild(this); 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 falied 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(); } }
// <summary> // The mapping view model contains a MappingFunctionScalarProperty for every parameter in the function. The user can clear out the // underlying scalar property, but that doesn't remove or add the MappingFunctionScalarProperty. 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(MappingModificationFunctionMapping.Function != null, "The parent item isn't set up correctly"); if (propertiesChain == null || context == null || ScalarProperty != null || MappingModificationFunctionMapping == null) { return; } Debug.Assert(propertiesChain.Count > 0, "propertiesChain cannot be empty"); if (propertiesChain.Count <= 0) { return; } Context = context; var mf = MappingModificationFunctionMapping.ModificationFunction; if (null == mf) { Debug.Fail("this.MappingModificationFunctionMapping.ModificationFunction is null"); return; } // use the stored Parameter var parameter = StoreParameter; if (parameter == null) { return; } // create a context if we weren't passed one if (cpc == null) { cpc = new CommandProcessorContext( Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateScalarProperty); } // create the FunctionScalarProperty command (including any intermediate ComplexProperty's or AssociationEnd's) var version = (MappingModificationFunctionMapping.ModificationFunctionType == ModificationFunctionType.Update ? ModelConstants.FunctionScalarPropertyVersionCurrent : null); var cmd = new CreateFunctionScalarPropertyTreeCommand(mf, propertiesChain, _pointingNavProperty, parameter, version); // set up our post event to fix up the view model cmd.PostInvokeEvent += (o, eventsArgs) => { var fsp = cmd.FunctionScalarProperty; Debug.Assert(fsp != null, "CreateFunctionScalarPropertyTreeCommand did not create a FunctionScalarProperty"); // 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 parameter in the function) ModelItem = fsp; }; try { // now make the change var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); } catch { ModelItem = null; throw; } }
// <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; } }
protected override void InvokeInternal(CommandProcessorContext cpc) { var artifact = cpc.EditingContext.GetEFArtifactService().Artifact; if (null == artifact) { Debug.Fail("null artifact not allowed"); return; } // safety check, this should never be hit Debug.Assert(_schemaProcedure != null, "InvokeInternal is called when _schemaProcedure is null"); if (null == _schemaProcedure) { throw new InvalidOperationException("InvokeInternal is called when _schemaProcedure is null."); } var cModel = artifact.ConceptualModel(); if (null == cModel) { Debug.Fail("ConceptualEntityModel not allowed"); return; } var cContainer = cModel.FirstEntityContainer as ConceptualEntityContainer; if (null == cContainer) { Debug.Fail("ConceptualEntityContainer not allowed"); return; } var sModel = artifact.StorageModel(); if (null == sModel) { Debug.Fail("null StorageEntityModel not allowed"); return; } // determine matching Function var funcObj = DatabaseObject.CreateFromSchemaProcedure(_schemaProcedure); var function = ModelHelper.FindFunction(sModel, funcObj); if (null == function) { // in some error scenarios where the model has not been properly created we can be asked to create a FunctionImport for a Function which does not exist // if so just return without creating return; } // do not produce FunctionImports for composable Functions unless _shouldCreateComposableFunctionImport is true if (false == _shouldCreateComposableFunctionImport && function.IsComposable.Value) { return; } // determine FunctionImport name and make sure it is unique var functionImportName = OverrideNameValue; if (String.IsNullOrWhiteSpace(functionImportName)) { if (null == function.LocalName || string.IsNullOrEmpty(function.LocalName.Value)) { Debug.Fail("null or empty LocalName attribute for matching Function " + function); return; } functionImportName = ModelHelper.GetUniqueName(typeof(FunctionImport), cContainer, function.LocalName.Value); } else { #if DEBUG string errorMessage; var isUnique = ModelHelper.IsUniqueName(typeof(FunctionImport), cContainer, functionImportName, false, out errorMessage); Debug.Assert(isUnique, "If we gave CreateMatchingFunctionImportCommand a name, it should have been unique"); #endif } object returnType = null; ComplexType existingComplexTypeReturnType = null; if (OverrideReturnTypeValue == null) { // get return type of the Function returnType = ConstructReturnType(_schemaProcedure, cModel, sModel, functionImportName); if (null == returnType) { Debug.Fail("cannot determine return type for schemaProcedure " + _schemaProcedure); return; } } else { if (OverrideReturnTypeValue.Equals(ModelConstants.NoneValue, StringComparison.Ordinal)) { returnType = Resources.NoneDisplayValueUsedForUX; } else { var rawValue = ModelHelper.UnwrapCollectionAroundFunctionImportReturnType(OverrideReturnTypeValue); // Here we attempt to find the corresponding ReturnType for the given ReturnTypeOverride. // The ReturnTypeOverride will be specified as the actual XAttribute value of the return type if (OverrideEntitySetValue != null) { if (ModelHelper.FindEntitySet(cpc.Artifact.ConceptualModel(), OverrideEntitySetValue) != null) { // ReturnType is an EntityType returnType = ModelHelper.FindEntityTypeViaSymbol(cpc.Artifact.ConceptualModel(), rawValue); } } else if (!ModelHelper.AllPrimitiveTypes(artifact.SchemaVersion).Contains(rawValue)) { // ReturnType is a ComplexType existingComplexTypeReturnType = ModelHelper.FindComplexType(cpc.Artifact.ConceptualModel(), rawValue); returnType = existingComplexTypeReturnType; } else { returnType = rawValue; } } } // Composable functions that do not return collections (e.g. scalar valued functions) are not supported // and should not be imported to the conceptual model if (Resources.NoneDisplayValueUsedForUX.Equals(returnType) && function.IsComposable.Value) { return; } // list of commands to be executed IList <Command> commands = new List <Command>(); // if return type is the name of a ComplexType then create a new matching ComplexType CreateComplexTypeCommand createComplexTypeCommand = null; if (OverrideReturnTypeValue == null && returnType is string && false == Resources.NoneDisplayValueUsedForUX.Equals(returnType)) { createComplexTypeCommand = AddCreateComplexTypeCommands(sModel, returnType as string, _schemaProcedure.RawColumns, commands); } // if we created a ComplexType above then pass that as a pre-req to the CreateFunctionImport command, // otherwise just create the FunctionImport without the pre-req CreateFunctionImportCommand cmdFuncImp; if (createComplexTypeCommand == null) { if (returnType is EdmType) { // For the case where the FunctionImport should have a return type which is not a Complex Type but // simply a C-side primitive type we have to pass the _name_ of the C-side primitive type to // CreateFunctionImportCommand, rather than the type itself returnType = (returnType as EdmType).Name; } cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, returnType); } else { cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, createComplexTypeCommand); } commands.Add(cmdFuncImp); // now create the FunctionImportMapping to map the S-side Function to the C-side FunctionImport if (null != artifact.MappingModel() && null != artifact.MappingModel().FirstEntityContainerMapping) { var cmdFuncImpMapping = new CreateFunctionImportMappingCommand( artifact.MappingModel().FirstEntityContainerMapping, function, cmdFuncImp.Id); cmdFuncImpMapping.AddPreReqCommand(cmdFuncImp); commands.Add(cmdFuncImpMapping); IDictionary <string, string> mapPropertyNameToColumnName = null; if (_schemaProcedure != null) { mapPropertyNameToColumnName = ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping( _schemaProcedure.RawColumns.Select(c => c.Name).ToList()); } // Create explicit function-import result type mapping if the return type is a complex type. if (createComplexTypeCommand != null) { commands.Add( new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, createComplexTypeCommand) { CreateDefaultScalarProperties = true, PropertyNameToColumnNameMap = mapPropertyNameToColumnName }); } else if (OverrideReturnTypeValue != null && existingComplexTypeReturnType != null) { commands.Add( new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, existingComplexTypeReturnType) { CreateDefaultScalarProperties = true, PropertyNameToColumnNameMap = mapPropertyNameToColumnName }); } } // now invoke the list of commands if (null != commands) { var cp = new CommandProcessor(cpc, commands); cp.Invoke(); // assign the generated FunctionImport so this command can be used as input for others _generatedFunctionImport = cmdFuncImp.FunctionImport; } }
// <summary> // This lets you switch the underlyingModelItem. // </summary> // <param name="cpc">The transaction to use for this entire process, cannot be null</param> // <param name="context">The current EditingContext</param> // <param name="newUnderlyingModelItem">The new model item to switch to</param> // <param name="deleteModelItemOnly">If 'true' then the MappingEFElement will just have its model item switched, if 'false' then a new MappingEFElement will be create and this one will be deleted</param> internal void SwitchModelItem( CommandProcessorContext cpc, EditingContext context, EFElement newUnderlyingModelItem, bool deleteModelItemOnly) { Debug.Assert(cpc != null, "You should send a cpc to this function so that the entire switch is in a single transaction"); var cmd = new DelegateCommand( () => { if (deleteModelItemOnly) { DeleteModelItemsRecursive(this, cpc); CreateModelItem(cpc, context, newUnderlyingModelItem); } else { Delete(cpc); var newElement = CreateCreatorNodeCopy(); newElement.CreateModelItem(cpc, context, newUnderlyingModelItem); } }); var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); }
/// <summary> /// Invokes a single command against the CommandProcessor. /// </summary> internal static void InvokeSingleCommand(CommandProcessorContext cpc, Command cmd) { var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert(cpc != null, "InvokeInternal is called when ExitingFunctionScalarProperty is null."); // safety check, this should never be hit if (_existingFunctionScalarProperty == null) { throw new InvalidOperationException("InvokeInternal is called when ExitingFunctionScalarProperty is null."); } if (_propChain == null && _pointingNavProp == null && _param == null && _version != null) { // setting new version only if (string.Compare(_existingFunctionScalarProperty.Version.Value, _version, StringComparison.CurrentCulture) != 0) { var mfAncestor = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction; Debug.Assert( mfAncestor != null, "Bad attempt to set version on FunctionScalarProperty which does not have a ModificationFunction ancestor"); if (mfAncestor != null) { Debug.Assert( mfAncestor.FunctionType == ModificationFunctionType.Update, "Bad attempt to set version on FunctionScalarProperty which has a ModificationFunction ancestor whose FunctionType is " + mfAncestor.FunctionType.ToString() + ". Should be " + ModificationFunctionType.Update.ToString()); if (mfAncestor.FunctionType == ModificationFunctionType.Update) { _existingFunctionScalarProperty.Version.Value = _version; } } } _updatedFunctionScalarProperty = _existingFunctionScalarProperty; return; } // if not just setting version then need to delete and re-create FunctionScalarProperty // to allow for changes in properties chain // where nulls have been passed in, use existing values (except for _pointingNavProp where null // indicates "use no NavProp for the new property") var mf = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction; Debug.Assert(mf != null, "Bad attempt to change FunctionScalarProperty which does not have a ModificationFunction ancestor"); if (mf == null) { return; } var propChain = (_propChain != null ? _propChain : _existingFunctionScalarProperty.GetMappedPropertiesList()); var parameter = (_param != null ? _param : _existingFunctionScalarProperty.ParameterName.Target); var version = (_version != null ? _version : _existingFunctionScalarProperty.Version.Value); // now construct delete command for existing FunctionScalarProperty followed by create with new properties var cmd1 = _existingFunctionScalarProperty.GetDeleteCommand(); var cmd2 = new CreateFunctionScalarPropertyTreeCommand(mf, propChain, _pointingNavProp, parameter, version); cmd2.PostInvokeEvent += (o, eventsArgs) => { _updatedFunctionScalarProperty = cmd2.FunctionScalarProperty; Debug.Assert( _updatedFunctionScalarProperty != null, "CreateFunctionScalarPropertyTreeCommand should not result in null FunctionScalarProperty"); }; var cp = new CommandProcessor(cpc, cmd1, cmd2); try { cp.Invoke(); } finally { _updatedFunctionScalarProperty = null; } }
internal void CreateModelItem(CommandProcessorContext cpc, EditingContext context, string columnName) { 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(_property != null, "The _property cannot be null."); Debug.Assert( MappingFunctionImport.FunctionImport != null && MappingFunctionImport.FunctionImportMapping != null, "The parent item isn't set up correctly"); Context = context; var fi = MappingFunctionImport.FunctionImport; var fim = MappingFunctionImport.FunctionImportMapping; if (_property != null && fi != null && fim != null) { // get the ReturnType of the FunctionImport EntityType entityType = null; ComplexType complexType = null; if (fi.IsReturnTypeEntityType) { entityType = fi.ReturnTypeAsEntityType.Target; } else if (fi.IsReturnTypeComplexType && fi.ReturnTypeAsComplexType.Target != null) { complexType = fi.ReturnTypeAsComplexType.Target; } // create a context if we weren't passed one if (cpc == null) { cpc = new CommandProcessorContext( Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_ChangeScalarProperty); } // first we need to create a FunctionImportTypeMapping element (either EntityTypeMapping or ComplexTypeMapping) var cmd = entityType != null ? new CreateFunctionImportTypeMappingCommand(MappingFunctionImport.FunctionImportMapping, entityType) : new CreateFunctionImportTypeMappingCommand(MappingFunctionImport.FunctionImportMapping, complexType); // create the ScalarProperty var cmd2 = new CreateFunctionImportScalarPropertyCommand(cmd, _property, columnName); // set up our post event to fix up the view model cmd2.PostInvokeEvent += (o, eventsArgs) => { var sp = cmd2.ScalarProperty; Debug.Assert(sp != null, "Didn't get good ScalarProperty out of the command"); // 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 each property) ModelItem = sp; }; // now make the change var cp = new CommandProcessor(cpc, cmd, cmd2); cp.Invoke(); } }