// <summary> // Creates commands to remove function imports and complex types corresponding to results if ones exist. // </summary> // <param name="designArtifact">Artifact.</param> // <returns>IEnumerable of commands for deleting function imports and corresponding complex types.</returns> // <remarks> // This function should be called only from RunFinished() method as we don't check whether complex types we // are removing are not used by other function imports or entities. // </remarks> private static IEnumerable <Command> CreateRemoveFunctionImportCommands(EntityDesignArtifact designArtifact) { // we were instructed not to create FunctionImports - but runtime has created them automatically so actually need to delete any which have been created var model = designArtifact.ConceptualModel; var cec = (ConceptualEntityContainer)model.FirstEntityContainer; foreach (var fi in cec.FunctionImports()) { yield return(fi.GetDeleteCommand()); if (fi.IsReturnTypeComplexType) { var complexType = model.ComplexTypes().SingleOrDefault( c => ReferenceEquals(c, fi.ReturnTypeAsComplexType.Target)); Debug.Assert( complexType != null, string.Format("Complex type {0} for FunctionImport {1} does not exist", complexType.Name, fi.Name)); if (complexType != null) { yield return(complexType.GetDeleteCommand()); } } } }
private void TestLoadingArtifact(Project project, string filePath, ArtifactStatus expectedArtifactStatus) { Assert.IsNotNull(expectedArtifactStatus); // get a new artifact, which will automatically open up the EDMX file in VS EntityDesignArtifact entityDesignArtifact = null; try { var edmxProjectItem = project.GetProjectItemByName(Path.GetFileName(filePath)); Assert.IsNotNull(edmxProjectItem); Dte.OpenFile(edmxProjectItem.FileNames[0]); entityDesignArtifact = (EntityDesignArtifact)_efArtifactHelper.GetNewOrExistingArtifact( TestUtils.FileName2Uri(edmxProjectItem.FileNames[0])); Assert.AreEqual(expectedArtifactStatus.IsStructurallySafe, entityDesignArtifact.IsStructurallySafe); Assert.AreEqual(expectedArtifactStatus.IsVersionSafe, entityDesignArtifact.IsVersionSafe); Assert.AreEqual(expectedArtifactStatus.IsDesignerSafe, entityDesignArtifact.IsDesignerSafe); } finally { if (entityDesignArtifact != null) { Dte.CloseDocument(entityDesignArtifact.Uri.LocalPath, false); } } }
internal MappingModel(EntityDesignArtifact parent, XElement element) : base(parent, element) { if (parent != null) { parent.MappingModel = this; } }
internal ConceptualEntityModel(EntityDesignArtifact parent, XElement element) : base(parent, element) { if (parent != null) { parent.ConceptualModel = this; } }
internal ConceptualEntityModel(EntityDesignArtifact parent, XElement element) : base(parent, element) { if (parent != null) { parent.ConceptualModel = this; } }
internal StorageEntityModel(EntityDesignArtifact parent, XElement element) : base(parent, element) { if (parent != null) { parent.StorageModel = this; } }
/// <summary> /// Retarget Artifact Xml Namespace and reload. /// </summary> internal static void RetargetArtifactXmlNamespaces( CommandProcessorContext cpc, EntityDesignArtifact artifact, Version targetSchemaVersion) { // no need to re-parse - ReloadArtifact will do this CommandProcessor.InvokeSingleCommand( cpc, new RetargetXmlNamespaceCommand(artifact, targetSchemaVersion, reparseArtifact: false)); // We need to ensure the command is committed before we reload the artifact. artifact.ReloadArtifact(); artifact.IsDirty = true; }
/// <summary> /// Retarget Artifact Xml Namespace and reload. /// </summary> internal static void RetargetArtifactXmlNamespaces( CommandProcessorContext cpc, EntityDesignArtifact artifact, Version targetSchemaVersion) { // no need to re-parse - ReloadArtifact will do this CommandProcessor.InvokeSingleCommand( cpc, new RetargetXmlNamespaceCommand(artifact, targetSchemaVersion, reparseArtifact: false)); // We need to ensure the command is committed before we reload the artifact. artifact.ReloadArtifact(); artifact.IsDirty = true; }
private void RefactorRenameTest(string projectName, Action <EntityDesignArtifact, CommandProcessorContext, object> test) { var modelEdmxFilePath = Path.Combine(TestContext.DeploymentDirectory, @"TestData\Model\v3\PubSimple.edmx"); var dte = VsIdeTestHostContext.Dte; var serviceProvider = VsIdeTestHostContext.ServiceProvider; UITestRunner.Execute( () => { EntityDesignArtifact entityDesignArtifact = null; try { var project = dte.CreateProject( TestContext.TestRunDirectory, projectName, DteExtensions.ProjectKind.Executable, DteExtensions.ProjectLanguage.CSharp); var projectItem = dte.AddExistingItem(new FileInfo(modelEdmxFilePath).FullName, project); dte.OpenFile(projectItem.FileNames[0]); entityDesignArtifact = (EntityDesignArtifact) new EFArtifactHelper(EFArtifactHelper.GetEntityDesignModelManager(serviceProvider)) .GetNewOrExistingArtifact(TestUtils.FileName2Uri(projectItem.FileNames[0])); var editingContext = _package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(entityDesignArtifact.Uri); var cpc = new CommandProcessorContext( editingContext, "DiagramTest" + projectName, "DiagramTestTxn" + projectName, entityDesignArtifact); var programDocData = VSHelpers.GetDocData( serviceProvider, Path.Combine(Path.GetDirectoryName(project.FullName), "Program.cs")); Debug.Assert(programDocData != null, "Could not get DocData for program file"); var textLines = VSHelpers.GetVsTextLinesFromDocData(programDocData); Debug.Assert(textLines != null, "Could not get VsTextLines for program DocData"); VsUtils.SetTextForVsTextLines(textLines, string.Format(PubSimpleProgramText, projectName)); test(entityDesignArtifact, cpc, programDocData); } catch (Exception ex) { TestContext.WriteLine(ex.ToString()); throw; } finally { if (entityDesignArtifact != null) { entityDesignArtifact.Dispose(); } dte.CloseSolution(false); } }); }
public EnumTypeViewModel(EntityDesignArtifact artifact, string underlyingType) { Initialize(); _underlyingType = String.IsNullOrWhiteSpace(underlyingType) ? ModelConstants.Int32PropertyType : underlyingType; _isFlag = false; _name = String.Empty; _artifact = artifact; _isValid = false; _externalTypeName = String.Empty; _isReferenceExternalType = false; }
private StorageMappingItemCollection ValidateMapping( EntityDesignArtifact designArtifact, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection) { Debug.Assert(designArtifact != null, "designArtifact != null"); Debug.Assert(edmItemCollection != null, "edmItemCollection != null"); Debug.Assert(storeItemCollection != null, "storeItemCollection != null"); var artifactSet = designArtifact.ArtifactSet; if (designArtifact.MappingModel == null) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_MappingModelMissing, designArtifact, ErrorCodes.ErrorValidatingArtifact_MappingModelMissing, ErrorClass.Runtime_MSL)); return(null); } if (SchemaManager.GetSchemaVersion(designArtifact.MappingModel.XElement.Name.Namespace) > _targetEntityFrameworkRuntimeVersion) { // the xml namespace of the mapping node is for a later version of the runtime than we are validating against artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_InvalidMSLNamespaceForTargetFrameworkVersion, designArtifact.MappingModel, ErrorCodes.ErrorValidatingArtifact_InvalidMSLNamespaceForTargetFrameworkVersion, ErrorClass.Runtime_MSL)); return(null); } using (var reader = CreateXmlReader(designArtifact, designArtifact.MappingModel.XElement)) { IList <EdmSchemaError> mappingErrors; var mappingItemCollection = StorageMappingItemCollection.Create( edmItemCollection, storeItemCollection, new[] { reader }, null, out mappingErrors); Debug.Assert(mappingErrors != null); ProcessErrors(mappingErrors, designArtifact, ErrorClass.Runtime_MSL); return(mappingItemCollection); } }
private void ChangeEntityTypesFillColorTest( string projectName, Color fillColor, Action <EntityDesignArtifact, CommandProcessorContext> runTest) { var modelPath = Path.Combine(TestContext.DeploymentDirectory, @"TestData\Model\v3\PubSimple.edmx"); UITestRunner.Execute(TestContext.TestName, () => { EntityDesignArtifact entityDesignArtifact = null; Project project = null; try { project = Dte.CreateProject( TestContext.TestRunDirectory, projectName, DteExtensions.ProjectKind.Executable, DteExtensions.ProjectLanguage.CSharp); var projectItem = Dte.AddExistingItem(modelPath, project); Dte.OpenFile(projectItem.FileNames[0]); entityDesignArtifact = (EntityDesignArtifact) new EFArtifactHelper(EFArtifactHelper.GetEntityDesignModelManager(ServiceProvider)) .GetNewOrExistingArtifact(TestUtils.FileName2Uri(projectItem.FileNames[0])); var editingContext = _package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(entityDesignArtifact.Uri); var commandProcessorContext = new CommandProcessorContext( editingContext, "DiagramTest", "DiagramTestTxn", entityDesignArtifact); foreach (var ets in entityDesignArtifact.DesignerInfo.Diagrams.FirstDiagram.EntityTypeShapes) { CommandProcessor.InvokeSingleCommand( commandProcessorContext, new UpdateDefaultableValueCommand <Color>(ets.FillColor, fillColor)); } runTest(entityDesignArtifact, commandProcessorContext); } finally { if (entityDesignArtifact != null) { entityDesignArtifact.Dispose(); } if (project != null) { Dte.CloseSolution(false); } } }); }
internal static void DoMigrate(CommandProcessorContext cpc, EntityDesignArtifact artifact) { var xmlModelProvider = artifact.XmlModelProvider as VSXmlModelProvider; Debug.Assert(xmlModelProvider != null, "Artifact's model provider is not type of VSXmlModelProvider."); if ((xmlModelProvider != null) && (xmlModelProvider.UndoManager != null)) { var undoManager = xmlModelProvider.UndoManager; try { // We need to temporarily disable the Undo Manager because this operation is not undoable. if (undoManager != null) { undoManager.Enable(0); } var command = new MigrateDiagramInformationCommand(artifact); var processor = new CommandProcessor(cpc, shouldNotifyObservers: false); processor.EnqueueCommand(command); processor.Invoke(); Debug.Assert(artifact.DiagramArtifact != null, "Diagram artifact should have been created by now."); if (artifact.DiagramArtifact != null) { // Ensure that diagram file is added to the project. var service = PackageManager.Package.GetService(typeof(DTE)) as DTE; service.ItemOperations.AddExistingItem(artifact.DiagramArtifact.Uri.LocalPath); // Reload the artifacts. artifact.ReloadArtifact(); artifact.IsDirty = true; // The code below ensures mapping window and model-browser window are refreshed. Debug.Assert( PackageManager.Package.DocumentFrameMgr != null, "Could not find the DocumentFrameMgr for this package"); if (PackageManager.Package.DocumentFrameMgr != null) { PackageManager.Package.DocumentFrameMgr.SetCurrentContext(cpc.EditingContext); } } } finally { if (undoManager != null) { undoManager.Enable(1); } } } }
// internal static to make it more testable internal static CommandProcessor PrepareCommandsAndIntegrityChecks( ModelBuilderSettings modelBuilderSettings, EditingContext editingContext, EntityDesignArtifact designArtifact) { Debug.Assert(modelBuilderSettings != null, "modelBuilderSettings != null"); Debug.Assert(editingContext != null, "editingContext != null"); Debug.Assert(designArtifact != null, "artifact != null"); var commands = new List <Command>(); if (modelBuilderSettings.NewFunctionSchemaProcedures != null && modelBuilderSettings.NewFunctionSchemaProcedures.Count > 0) { // user selected to create new FunctionImports, but don't create the composable ones as these have already been created by the runtime ProgressDialogHelper.ProcessStoredProcedureReturnTypeInformation( designArtifact, modelBuilderSettings.NewFunctionSchemaProcedures, commands, shouldCreateComposableFunctionImports: false); } else { commands.AddRange(CreateRemoveFunctionImportCommands(designArtifact)); } // for SqlServer and SqlServerCe we need to add integrity checks - see the comment below if (commands.Count > 0 || designArtifact.IsSqlFamilyProvider()) { // set up CommandProcessorContext var cpc = new CommandProcessorContext( editingContext, EfiTransactionOriginator.CreateNewModelId, Resources.Tx_CreateFunctionImport); // We propagate facets by default only for Sql Server or Sql Server CE since for other providers facets in C-Space might be intentionally // out of sync with facets from S-Space and we should not break this. For Sql Server and Sql Server CE facets should be in sync in most cases. if (designArtifact.IsSqlFamilyProvider()) { // Add integrity check to enforce synchronizing C-side Property facets to S-side values PropagateStoragePropertyFacetsToConceptualModel.AddRule(cpc, designArtifact); } return(new CommandProcessor(cpc, commands)); } // no commands or integrity checks to run return(null); }
private StoreItemCollection ValidateStoreModel(EntityDesignArtifact designArtifact) { Debug.Assert(designArtifact != null, "designArtifact != null"); var artifactSet = designArtifact.ArtifactSet; if (designArtifact.StorageModel == null) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_StorageModelMissing, designArtifact, ErrorCodes.ErrorValidatingArtifact_StorageModelMissing, ErrorClass.Runtime_SSDL)); return(null); } if (SchemaManager.GetSchemaVersion(designArtifact.StorageModel.XElement.Name.Namespace) > _targetEntityFrameworkRuntimeVersion) { // the xml namespace of the ssdl Schema node is for a later version of the runtime than we are validating against artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_InvalidSSDLNamespaceForTargetFrameworkVersion, designArtifact.StorageModel, ErrorCodes.ErrorValidatingArtifact_InvalidSSDLNamespaceForTargetFrameworkVersion, ErrorClass.Runtime_CSDL)); return(null); } using (var reader = CreateXmlReader(designArtifact, designArtifact.StorageModel.XElement)) { IList <EdmSchemaError> storeErrors; var storeItemCollection = StoreItemCollection.Create(new[] { reader }, null, _dependencyResolver, out storeErrors); Debug.Assert(storeErrors != null); // also process cached errors and warnings (if any) from reverse engineering db ProcessErrors( storeErrors.Concat(designArtifact.GetModelGenErrors() ?? Enumerable.Empty <EdmSchemaError>()), designArtifact, ErrorClass.Runtime_SSDL); return(storeItemCollection); } }
private static void ReplaceMsl(CommandProcessorContext cpc, EntityDesignArtifact existingArtifact, XmlReader newMsl) { Debug.Assert(null != existingArtifact, "Existing artifact is null"); if (null == existingArtifact) { return; } ReplaceModelRoot( cpc, existingArtifact.MappingModel, newMsl, newMslElement => { // create a new MappingModel object, add it back into the artifact and re-parse existingArtifact.MappingModel = new MappingModel(existingArtifact, newMslElement); existingArtifact.MappingModel.Parse(new HashSet <XName>()); Debug.Assert(EFElementState.Parsed == existingArtifact.MappingModel.State, "MappingModel State should be Parsed"); }); }
private static void ReplaceMsl(CommandProcessorContext cpc, EntityDesignArtifact existingArtifact, XmlReader newMsl) { Debug.Assert(null != existingArtifact, "Existing artifact is null"); if (null == existingArtifact) { return; } ReplaceModelRoot( cpc, existingArtifact.MappingModel, newMsl, newMslElement => { // create a new MappingModel object, add it back into the artifact and re-parse existingArtifact.MappingModel = new MappingModel(existingArtifact, newMslElement); existingArtifact.MappingModel.Parse(new HashSet<XName>()); Debug.Assert(EFElementState.Parsed == existingArtifact.MappingModel.State, "MappingModel State should be Parsed"); }); }
private EdmItemCollection ValidateConceptualModel(EntityDesignArtifact designArtifact) { Debug.Assert(designArtifact != null, "designArtifact != null"); var artifactSet = designArtifact.ArtifactSet; if (designArtifact.ConceptualModel == null) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_ConceptualModelMissing, designArtifact, ErrorCodes.ErrorValidatingArtifact_ConceptualModelMissing, ErrorClass.Runtime_CSDL)); return(null); } if (SchemaManager.GetSchemaVersion(designArtifact.ConceptualModel.XElement.Name.Namespace) > _targetEntityFrameworkRuntimeVersion) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_InvalidCSDLNamespaceForTargetFrameworkVersion, designArtifact.ConceptualModel, ErrorCodes.ErrorValidatingArtifact_InvalidCSDLNamespaceForTargetFrameworkVersion, ErrorClass.Runtime_CSDL)); return(null); } using (var reader = CreateXmlReader(designArtifact, designArtifact.ConceptualModel.XElement)) { IList <EdmSchemaError> modelErrors; var edmItemCollection = EdmItemCollection.Create(new[] { reader }, null, out modelErrors); Debug.Assert(modelErrors != null); ProcessErrors(modelErrors, designArtifact, ErrorClass.Runtime_CSDL); return(edmItemCollection); } }
private static void ReplaceSsdl(CommandProcessorContext cpc, EntityDesignArtifact existingArtifact, XElement newSsdl) { // find the XObject representing the existing StorageModel Schema element var existingStorageModelNode = existingArtifact.StorageModel.XObject as XElement; Debug.Assert(existingStorageModelNode != null, "existingStorageModelNode is null"); // find the parent of the existing StorageModel Schema element var existingStorageModelParentNode = existingStorageModelNode.Parent; // delete the old StorageModel but do not delete its anti-dependencies if (null != existingArtifact.StorageModel) { var deleteStorageModelCommand = new DeleteEFElementCommand(existingArtifact.StorageModel, true, false); DeleteEFElementCommand.DeleteInTransaction(cpc, deleteStorageModelCommand); } // this will clone the source element var ssdlSchemaElement = new XElement(newSsdl); // add ssdlSchemaElement to the parent of the previously existing Storage node existingStorageModelParentNode.Add(ssdlSchemaElement); // create a new StorageModel object, add it back into the artifact and re-parse existingArtifact.StorageModel = new StorageEntityModel(existingArtifact, ssdlSchemaElement); existingArtifact.StorageModel.Parse(new HashSet <XName>()); Debug.Assert( EFElementState.Parsed == existingArtifact.StorageModel.State, "StorageModel State should be Parsed, instead it is " + existingArtifact.StorageModel.State); // normalize and resolve the StorageModel XmlModelHelper.NormalizeAndResolve(existingArtifact.StorageModel); Debug.Assert( EFElementState.Resolved == existingArtifact.StorageModel.State, "StorageModel State should be Resolved, instead it is " + existingArtifact.StorageModel.State); }
public EnumTypeViewModel(EnumType enumType) { Initialize(); Debug.Assert(enumType != null, "Parameter enum type is null"); if (enumType != null) { _enumType = enumType; _artifact = enumType.Artifact as EntityDesignArtifact; _isFlag = enumType.IsFlags.Value; _name = enumType.Name.Value; _underlyingType = enumType.UnderlyingType.Value; _externalTypeName = enumType.ExternalTypeName.Value; _isReferenceExternalType = (String.IsNullOrWhiteSpace(_externalTypeName) == false); foreach (var member in enumType.Members()) { var vm = new EnumTypeMemberViewModel(this, member); vm.PropertyChanged += enumTypeMember_PropertyChanged; Members.Add(vm); } } _isValid = true; }
internal static void GenerateDatabaseScriptFromModel(EntityDesignArtifact artifact) { VsUtils.EnsureProvider(artifact); var project = VSHelpers.GetProjectForDocument(artifact.Uri.LocalPath, PackageManager.Package); var sp = Services.ServiceProvider; ModelBuilderWizardForm form; ModelBuilderWizardForm.WizardMode startMode; ModelBuilderSettings settings; // Start the hourglass, especially because we'll be incurring a perf hit from validating using (new VsUtils.HourglassHelper()) { // Before running the Generate Database wizard, we have to make sure that the C-Side validates VisualStudioEdmxValidator.LoadAndValidateFiles(artifact.Uri); if ( artifact.ArtifactSet.GetAllErrors() .Count(ei => ei.ErrorClass == ErrorClass.Runtime_CSDL || ei.ErrorClass == ErrorClass.Escher_CSDL) > 0) { VsUtils.ShowErrorDialog(Resources.DatabaseCreation_ValidationFailed); return; } // set up ModelBuilderSettings settings = SetupSettingsAndModeForDbPages( sp, project, artifact, false, ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndDBGenSummary, ModelBuilderWizardForm.WizardMode.PerformDBGenSummaryOnly, out startMode); form = new ModelBuilderWizardForm(sp, settings, startMode); } var originalSchemaVersion = settings.TargetSchemaVersion; try { // start the ModelBuilderWizardForm; this will start the workflow in another thread. form.Start(); } catch (Exception e) { VsUtils.ShowErrorDialog( String.Format( CultureInfo.CurrentCulture, Resources.ModelObjectItemWizard_UnexpectedExceptionHasOccurred, e.Message)); return; } // if Wizard was cancelled or the user hit 'X' to close window // no need for any further action if (form.WizardCancelled || !form.WizardFinished) { return; } // If database was configured, add DbContext templates if (startMode == ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndDBGenSummary) { var edmxItem = VsUtils.GetProjectItemForDocument(artifact.Uri.LocalPath, sp); new DbContextCodeGenerator().AddDbContextTemplates(edmxItem, settings.UseLegacyProvider); // We need to reload the artifact if we updated the edmx as part of generating // model from the database. if (settings.TargetSchemaVersion != originalSchemaVersion) { artifact.ReloadArtifact(); } } }
// internal for testing internal void ProcessErrors(IEnumerable<EdmSchemaError> errors, EntityDesignArtifact defaultArtifactForError, ErrorClass errorClass) { Debug.Assert(errors != null, "errors != null"); Debug.Assert(defaultArtifactForError != null, "defaultArtifactForError != null"); var artifactSet = defaultArtifactForError.ArtifactSet; foreach (var error in errors) { var efObject = EdmSchemaError2EFObject(error, defaultArtifactForError); if (error.ErrorCode == (int)ErrorCode.NotInNamespace) { // we want to replace runtime error for missing complex property type with ours. This // is classified as a Runtime_CSDL error even though we are using an Escher error code // since we are basically re-interpreting a runtime error. var property = efObject as ComplexConceptualProperty; if (property != null && property.ComplexType.RefName == Resources.ComplexPropertyUndefinedType) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, string.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_UndefinedComplexPropertyType, property.LocalName.Value), property, ErrorCodes.ESCHER_VALIDATOR_UNDEFINED_COMPLEX_PROPERTY_TYPE, ErrorClass.Runtime_CSDL)); continue; } } else if (error.ErrorCode == (int)MappingErrorCode.InvalidAssociationSet && error.Severity == EdmSchemaErrorSeverity.Warning) { // this is a warning about AssociationSetMappings on fk associations for pk-to-pk associations being ignored. var associationSetMapping = efObject as AssociationSetMapping; Debug.Assert(associationSetMapping != null, "Warning 2005 reported on EFObject other than Association Set Mapping"); if (associationSetMapping != null) { artifactSet.AddError( new ErrorInfo( GetErrorInfoSeverity(error), string.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_IgnoreMappedFKAssociation, associationSetMapping.Name.RefName), efObject, error.ErrorCode, errorClass)); continue; } } var severity = error.ErrorCode == (int)MappingErrorCode.EmptyContainerMapping && ValidationHelper.IsStorageModelEmpty(defaultArtifactForError) ? ErrorInfo.Severity.WARNING : GetErrorInfoSeverity(error); artifactSet.AddError(new ErrorInfo(severity, error.Message, efObject, error.ErrorCode, errorClass)); } defaultArtifactForError.SetValidityDirtyForErrorClass(errorClass, false); }
private RetargetXmlNamespaceCommand(EntityDesignArtifact artifact, Version targetSchemaVersion, bool reparseArtifact) { _targetSchemaVersion = targetSchemaVersion; _artifact = artifact; _reparseArtifact = reparseArtifact; }
private void ValidateWithViewGen(StorageMappingItemCollection mappingItemCollection, EntityDesignArtifact designArtifact) { Debug.Assert(mappingItemCollection != null, "mappingItemCollection != null"); Debug.Assert(designArtifact != null, "designArtifact != null"); var errors = new List<EdmSchemaError>(); mappingItemCollection.GenerateViews(errors); ProcessErrors(errors, designArtifact, ErrorClass.Runtime_ViewGen); }
private RetargetXmlNamespaceCommand(EntityDesignArtifact artifact, Version targetSchemaVersion, bool reparseArtifact) { _targetSchemaVersion = targetSchemaVersion; _artifact = artifact; _reparseArtifact = reparseArtifact; }
private void ExecuteMigrateDiagramNodesTest(string projectName, Action <EntityDesignArtifact, CommandProcessorContext> runTest) { var modelPath = Path.Combine(TestContext.DeploymentDirectory, @"TestData\Model\v3\PubSimple.edmx"); UITestRunner.Execute( () => { EntityDesignArtifact entityDesignArtifact = null; Project project = null; try { project = Dte.CreateProject( TestContext.TestRunDirectory, projectName, DteExtensions.ProjectKind.Executable, DteExtensions.ProjectLanguage.CSharp); var projectItem = Dte.AddExistingItem(modelPath, project); Dte.OpenFile(projectItem.FileNames[0]); entityDesignArtifact = (EntityDesignArtifact) new EFArtifactHelper(EFArtifactHelper.GetEntityDesignModelManager(ServiceProvider)) .GetNewOrExistingArtifact(TestUtils.FileName2Uri(projectItem.FileNames[0])); Debug.Assert(entityDesignArtifact != null); var editingContext = _package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(entityDesignArtifact.Uri); // Create TransactionContext to indicate that the transactions are done from first diagram. // This is not used by MigrateDiagramInformationCommand but other commands in the callback methods. var transactionContext = new EfiTransactionContext(); transactionContext.Add( EfiTransactionOriginator.TransactionOriginatorDiagramId, new DiagramContextItem(entityDesignArtifact.DesignerInfo.Diagrams.FirstDiagram.Id.Value)); var commandProcessorContext = new CommandProcessorContext( editingContext, "MigrateDiagramNodesTest", projectName + "Txn", entityDesignArtifact, transactionContext); MigrateDiagramInformationCommand.DoMigrate(commandProcessorContext, entityDesignArtifact); Debug.Assert(entityDesignArtifact.DiagramArtifact != null); Debug.Assert( entityDesignArtifact.IsDesignerSafe, "Artifact should not be in safe mode after MigrateDiagramInformationCommand is executed."); Debug.Assert( new Uri(entityDesignArtifact.Uri.LocalPath + EntityDesignArtifact.EXTENSION_DIAGRAM) == entityDesignArtifact.DiagramArtifact.Uri); runTest(entityDesignArtifact, commandProcessorContext); } finally { if (entityDesignArtifact != null) { entityDesignArtifact.Dispose(); } if (project != null) { Dte.CloseSolution(false); } } }); }
// internal for testing internal void ProcessErrors(IEnumerable <EdmSchemaError> errors, EntityDesignArtifact defaultArtifactForError, ErrorClass errorClass) { Debug.Assert(errors != null, "errors != null"); Debug.Assert(defaultArtifactForError != null, "defaultArtifactForError != null"); var artifactSet = defaultArtifactForError.ArtifactSet; foreach (var error in errors) { var efObject = EdmSchemaError2EFObject(error, defaultArtifactForError); if (error.ErrorCode == (int)ErrorCode.NotInNamespace) { // we want to replace runtime error for missing complex property type with ours. This // is classified as a Runtime_CSDL error even though we are using an Escher error code // since we are basically re-interpreting a runtime error. var property = efObject as ComplexConceptualProperty; if (property != null && property.ComplexType.RefName == Resources.ComplexPropertyUndefinedType) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, string.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_UndefinedComplexPropertyType, property.LocalName.Value), property, ErrorCodes.ESCHER_VALIDATOR_UNDEFINED_COMPLEX_PROPERTY_TYPE, ErrorClass.Runtime_CSDL)); continue; } } else if (error.ErrorCode == (int)MappingErrorCode.InvalidAssociationSet && error.Severity == EdmSchemaErrorSeverity.Warning) { // this is a warning about AssociationSetMappings on fk associations for pk-to-pk associations being ignored. var associationSetMapping = efObject as AssociationSetMapping; Debug.Assert(associationSetMapping != null, "Warning 2005 reported on EFObject other than Association Set Mapping"); if (associationSetMapping != null) { artifactSet.AddError( new ErrorInfo( GetErrorInfoSeverity(error), string.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_IgnoreMappedFKAssociation, associationSetMapping.Name.RefName), efObject, error.ErrorCode, errorClass)); continue; } } var severity = error.ErrorCode == (int)MappingErrorCode.EmptyContainerMapping && ValidationHelper.IsStorageModelEmpty(defaultArtifactForError) ? ErrorInfo.Severity.WARNING : GetErrorInfoSeverity(error); artifactSet.AddError(new ErrorInfo(severity, error.Message, efObject, error.ErrorCode, errorClass)); } defaultArtifactForError.SetValidityDirtyForErrorClass(errorClass, false); }
private static bool ProcessAccumulatedInfo( EditingContext editingContext, EntityDesignArtifact existingArtifact, ModelBuilderSettings settings) { var schemaVersionChanged = existingArtifact.SchemaVersion != settings.TargetSchemaVersion; EntityDesignModelManager tempModelManager = null; FileInfo tempEdmxFile = null; Uri tempEdmxFileUri = null; try { // set up new temporary ModelManager // NOTE: use an EFArtifact with VSArtifactSet. This is so we get the in-vs behavior of artifact sets, // but don't rely on VS loading the model into the RDT, etc.. tempModelManager = new EntityDesignModelManager(new EFArtifactFactory(), new VSArtifactSetFactory()); tempEdmxFile = ConstructTempEdmxFile(settings); tempEdmxFileUri = new Uri(tempEdmxFile.FullName, UriKind.Absolute); var tempArtifactBasedOnDatabase = tempModelManager.GetNewOrExistingArtifact(tempEdmxFileUri, new VanillaXmlModelProvider()); // if a model generation extension has changed the model, ensure that it is // valid before we start to process it if (settings.HasExtensionChangedModel) { ValidateArtifact(tempModelManager, tempArtifactBasedOnDatabase, WizardKind.Generate); } // Note: later we want the diagram shapes and connectors to be created in the current active diagram // so set TransactionContext appropriately. EfiTransactionContext transactionContext = null; var contextItem = editingContext.Items.GetValue <DiagramManagerContextItem>(); if (contextItem != null && contextItem.DiagramManager != null) { var activeDiagram = contextItem.DiagramManager.ActiveDiagram; if (activeDiagram != null) { transactionContext = new EfiTransactionContext(); transactionContext.Add( EfiTransactionOriginator.TransactionOriginatorDiagramId, new DiagramContextItem(activeDiagram.DiagramId)); } } // clear search if active (Note: in Model.Tests it is OK for below to be null) var explorerInfo = editingContext.Items.GetValue <ExplorerWindow.ExplorerInfo>(); if (explorerInfo != null) { var explorerFrame = explorerInfo._explorerFrame; if (explorerFrame != null) { if (explorerFrame.SearchIsActive) { explorerFrame.ResetSearchCommand.Execute(null); } } } var cpc = new CommandProcessorContext( editingContext, EfiTransactionOriginator.UpdateModelFromDatabaseId, Resources.Tx_UpdateModelFromDatabase, null, transactionContext); if (schemaVersionChanged) { // changing namespaces must be done in a separate transaction otherwise XmlEditor // will not pick-up changes made to xml after namespaces are changed CommandProcessor.InvokeSingleCommand( cpc, new RetargetXmlNamespaceCommand(existingArtifact, settings.TargetSchemaVersion)); } // Update the existing artifact based on tempArtifactBasedOnDatabase var commands = new List <Command>(); var cmd = new UpdateModelFromDatabaseCommand(tempArtifactBasedOnDatabase); commands.Add(cmd); // set up our post event to clear out the error list cmd.PostInvokeEvent += (o, e) => { var errorList = ErrorListHelper.GetSingleDocErrorList(e.CommandProcessorContext.Artifact.Uri); if (errorList != null) { errorList.Clear(); } }; DesignerInfo designerInfo; if (existingArtifact.DesignerInfo().TryGetDesignerInfo(OptionsDesignerInfo.ElementName, out designerInfo)) { var optionsDesignerInfo = designerInfo as OptionsDesignerInfo; Debug.Assert(optionsDesignerInfo != null, "expected non-null optionsDesignerInfo"); if (optionsDesignerInfo != null) { // pluralization checkbox AddUpdateDesignerPropertyCommand( optionsDesignerInfo.CheckPluralizationInWizard, OptionsDesignerInfo.AttributeEnablePluralization, settings.UsePluralizationService, optionsDesignerInfo, commands); // include FKs in model checkbox AddUpdateDesignerPropertyCommand( optionsDesignerInfo.CheckIncludeForeignKeysInModel, OptionsDesignerInfo.AttributeIncludeForeignKeysInModel, settings.IncludeForeignKeysInModel, optionsDesignerInfo, commands); // ensure UseLegacyProvider is set AddUpdateDesignerPropertyCommand( optionsDesignerInfo.UseLegacyProvider, OptionsDesignerInfo.AttributeUseLegacyProvider, settings.UseLegacyProvider, optionsDesignerInfo, commands); } } // create a new FunctionImport for every new Function created (whether composable or not) // (or delete Functions if ProgressDialog did not finish successfully) // Note: this must take place as a DelegateCommand as ProcessStoredProcedureReturnTypeInformation() // can depend on finding the existing Functions to delete. And it won't find them until the // ReplaceSsdlCommand within UpdateModelFromDatabaseCommand has executed. var createMatchingFunctionImportsDelegateCommand = new DelegateCommand( () => { var functionImportCommands = new List <Command>(); ProgressDialogHelper.ProcessStoredProcedureReturnTypeInformation( existingArtifact, settings.NewFunctionSchemaProcedures, functionImportCommands, true); if (functionImportCommands.Count > 0) { new CommandProcessor(cpc, functionImportCommands) .Invoke(); } }); commands.Add(createMatchingFunctionImportsDelegateCommand); // if needed, create a command to dispatch any extensions if (EscherExtensionPointManager.LoadModelGenerationExtensions().Length > 0) { var dispatchCommand = new DispatchToExtensionsCommand(settings); commands.Add(dispatchCommand); } // do all the work here in one transaction new CommandProcessor(cpc, commands) .Invoke(); // if an extension has changed the model, do a full reload if (schemaVersionChanged || settings.HasExtensionChangedModel) { return(true); } else { // reset the is-designer safe flag - this can be set incorrectly when the document is reloaded after ssdl has been updated, // but csdl & msl haven't. Here, the model is correct, but we need to get views to refresh themselves after we // reset the is-designer-safe flag. // Perf note: reloading the artifact can take some time - so only reload if IsDesignerSafe has changed var isDesignerSafeBefore = existingArtifact.IsDesignerSafe; existingArtifact.DetermineIfArtifactIsDesignerSafe(); var isDesignerSafeAfter = existingArtifact.IsDesignerSafe; if (isDesignerSafeAfter != isDesignerSafeBefore) { existingArtifact.FireArtifactReloadedEvent(); } } } finally { // remove tempArtifactBasedOnDatabase to dispose EFObject's properly if (tempEdmxFileUri != null && tempModelManager != null) { tempModelManager.ClearArtifact(tempEdmxFileUri); } // dispose of our temp model manager if (tempModelManager != null) { tempModelManager.Dispose(); } // delete temporary file if (tempEdmxFile != null && tempEdmxFile.Exists) { try { tempEdmxFile.Delete(); } catch (IOException) { // do nothing if delete fails } } } return(false); }
private EdmItemCollection ValidateConceptualModel(EntityDesignArtifact designArtifact) { Debug.Assert(designArtifact != null, "designArtifact != null"); var artifactSet = designArtifact.ArtifactSet; if (designArtifact.ConceptualModel == null) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_ConceptualModelMissing, designArtifact, ErrorCodes.ErrorValidatingArtifact_ConceptualModelMissing, ErrorClass.Runtime_CSDL)); return null; } if (SchemaManager.GetSchemaVersion(designArtifact.ConceptualModel.XElement.Name.Namespace) > _targetEntityFrameworkRuntimeVersion) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_InvalidCSDLNamespaceForTargetFrameworkVersion, designArtifact.ConceptualModel, ErrorCodes.ErrorValidatingArtifact_InvalidCSDLNamespaceForTargetFrameworkVersion, ErrorClass.Runtime_CSDL)); return null; } using (var reader = CreateXmlReader(designArtifact, designArtifact.ConceptualModel.XElement)) { IList<EdmSchemaError> modelErrors; var edmItemCollection = EdmItemCollection.Create(new[] { reader }, null, out modelErrors); Debug.Assert(modelErrors != null); ProcessErrors(modelErrors, designArtifact, ErrorClass.Runtime_CSDL); return edmItemCollection; } }
// Intentionally set this to private because we only want this command to be instantiated from static method and not to be combined with other command. private MigrateDiagramInformationCommand(EntityDesignArtifact artifact) { _artifact = artifact; }
// This command will replace root xml document of the edmx which requires reloading artifact. // But we need to commit the transaction before we can reload the artifact. The reason is that // XLinq representation of the parsed xml tree are not regenerated until the transaction is committed. // This command should not be combined with other commands unless it is executed as the last command in a // transaction since XmlEditor will not be aware of changes made to the Xml after we replace the root element internal RetargetXmlNamespaceCommand(EntityDesignArtifact artifact, Version targetSchemaVersion) : this(artifact, targetSchemaVersion, true) { }
private StoreItemCollection ValidateStoreModel(EntityDesignArtifact designArtifact) { Debug.Assert(designArtifact != null, "designArtifact != null"); var artifactSet = designArtifact.ArtifactSet; if (designArtifact.StorageModel == null) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_StorageModelMissing, designArtifact, ErrorCodes.ErrorValidatingArtifact_StorageModelMissing, ErrorClass.Runtime_SSDL)); return null; } if (SchemaManager.GetSchemaVersion(designArtifact.StorageModel.XElement.Name.Namespace) > _targetEntityFrameworkRuntimeVersion) { // the xml namespace of the ssdl Schema node is for a later version of the runtime than we are validating against artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_InvalidSSDLNamespaceForTargetFrameworkVersion, designArtifact.StorageModel, ErrorCodes.ErrorValidatingArtifact_InvalidSSDLNamespaceForTargetFrameworkVersion, ErrorClass.Runtime_CSDL)); return null; } using (var reader = CreateXmlReader(designArtifact, designArtifact.StorageModel.XElement)) { IList<EdmSchemaError> storeErrors; var storeItemCollection = StoreItemCollection.Create(new[] { reader }, null, _dependencyResolver, out storeErrors); Debug.Assert(storeErrors != null); // also process cached errors and warnings (if any) from reverse engineering db ProcessErrors( storeErrors.Concat(designArtifact.GetModelGenErrors() ?? Enumerable.Empty<EdmSchemaError>()), designArtifact, ErrorClass.Runtime_SSDL); return storeItemCollection; } }
// This command will replace root xml document of the edmx which requires reloading artifact. // But we need to commit the transaction before we can reload the artifact. The reason is that // XLinq representation of the parsed xml tree are not regenerated until the transaction is committed. // This command should not be combined with other commands unless it is executed as the last command in a // transaction since XmlEditor will not be aware of changes made to the Xml after we replace the root element internal RetargetXmlNamespaceCommand(EntityDesignArtifact artifact, Version targetSchemaVersion) : this(artifact, targetSchemaVersion, true) { }
private StorageMappingItemCollection ValidateMapping( EntityDesignArtifact designArtifact, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection) { Debug.Assert(designArtifact != null, "designArtifact != null"); Debug.Assert(edmItemCollection != null, "edmItemCollection != null"); Debug.Assert(storeItemCollection != null, "storeItemCollection != null"); var artifactSet = designArtifact.ArtifactSet; if (designArtifact.MappingModel == null) { artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_MappingModelMissing, designArtifact, ErrorCodes.ErrorValidatingArtifact_MappingModelMissing, ErrorClass.Runtime_MSL)); return null; } if (SchemaManager.GetSchemaVersion(designArtifact.MappingModel.XElement.Name.Namespace) > _targetEntityFrameworkRuntimeVersion) { // the xml namespace of the mapping node is for a later version of the runtime than we are validating against artifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, Resources.ErrorValidatingArtifact_InvalidMSLNamespaceForTargetFrameworkVersion, designArtifact.MappingModel, ErrorCodes.ErrorValidatingArtifact_InvalidMSLNamespaceForTargetFrameworkVersion, ErrorClass.Runtime_MSL)); return null; } using (var reader = CreateXmlReader(designArtifact, designArtifact.MappingModel.XElement)) { IList<EdmSchemaError> mappingErrors; var mappingItemCollection = StorageMappingItemCollection.Create( edmItemCollection, storeItemCollection, new[] { reader }, null, out mappingErrors); Debug.Assert(mappingErrors != null); ProcessErrors(mappingErrors, designArtifact, ErrorClass.Runtime_MSL); return mappingItemCollection; } }
internal static void UpdateModelFromDatabase(EntityDesignArtifact artifact) { VsUtils.EnsureProvider(artifact); var serviceProvider = Services.ServiceProvider; var project = VSHelpers.GetProjectForDocument(artifact.Uri.LocalPath, serviceProvider); // set up ModelBuilderSettings for startMode=PerformDatabaseConfigAndSelectTables ModelBuilderWizardForm.WizardMode startMode; var settings = SetupSettingsAndModeForDbPages( serviceProvider, project, artifact, true, ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndSelectTables, ModelBuilderWizardForm.WizardMode.PerformSelectTablesOnly, out startMode); settings.WizardKind = WizardKind.UpdateModel; // use existing storage namespace as new storage namespace if (null != artifact.StorageModel() && null != artifact.StorageModel().Namespace && !string.IsNullOrEmpty(artifact.StorageModel().Namespace.Value)) { settings.StorageNamespace = artifact.StorageModel().Namespace.Value; } // use existing model namespace as new model namespace (this only affects the temporary // artifact but there is a situation where the C-side EntityContainer has been given the // same name as the default model namespace where not setting this causes the temporary // artifact to be unreadable because of symbol clashes) if (null != artifact.ConceptualModel() && null != artifact.ConceptualModel().Namespace && !string.IsNullOrEmpty(artifact.ConceptualModel().Namespace.Value)) { settings.ModelNamespace = artifact.ConceptualModel().Namespace.Value; } settings.ModelBuilderEngine = new UpdateModelFromDatabaseModelBuilderEngine(); // call the ModelBuilderWizardForm var form = new ModelBuilderWizardForm(serviceProvider, settings, startMode); try { form.Start(); } catch (Exception e) { VsUtils.ShowErrorDialog( string.Format( CultureInfo.CurrentCulture, Resources.ModelObjectItemWizard_UnexpectedExceptionHasOccurred, e.Message)); return; } // if Wizard was cancelled or the user hit 'X' to close window // no need for any further action if (form.WizardCancelled || !form.WizardFinished) { return; } // Update the app. or web.config, register build providers etc ConfigFileHelper.UpdateConfig(settings); // use form.ModelBuilderSettings to look at accumulated info and // take appropriate action var editingContext = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(artifact.Uri); var shouldReloadArtifact = ProcessAccumulatedInfo(editingContext, artifact, settings); // If database was configured, add DbContext templates if (startMode == ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndSelectTables) { var edmxItem = VsUtils.GetProjectItemForDocument(artifact.Uri.LocalPath, serviceProvider); new DbContextCodeGenerator().AddDbContextTemplates(edmxItem, settings.UseLegacyProvider); } // We can reload only after we added EF references to the project otherwise we would get a watermark // saying that the schema version does not match the referenced EF version which would not be true. // If we reload becuase there was an extension that potentially modified the artifact then it does not matter. if (shouldReloadArtifact) { artifact.ReloadArtifact(); artifact.IsDirty = true; } }
private void ValidateWithViewGen(StorageMappingItemCollection mappingItemCollection, EntityDesignArtifact designArtifact) { Debug.Assert(mappingItemCollection != null, "mappingItemCollection != null"); Debug.Assert(designArtifact != null, "designArtifact != null"); var errors = new List <EdmSchemaError>(); mappingItemCollection.GenerateViews(errors); ProcessErrors(errors, designArtifact, ErrorClass.Runtime_ViewGen); }