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 ConfigFileUtils.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); }
internal static void UpdateModelFromDatabase(EntityDesignArtifact artifact) { VsUtils.EnsureProvider(artifact); var project = VSHelpers.GetProjectForDocument(artifact.Uri.LocalPath, PackageManager.Package); var serviceProvider = Services.ServiceProvider; // set up ModelBuilderSettings for startMode=PerformDatabaseConfigAndSelectTables ModelBuilderWizardForm.WizardMode startMode; ModelBuilderSettings settings; ModelBuilderEngine.SetupSettingsAndModeForDbPages( serviceProvider, project, artifact, true, ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndSelectTables, ModelBuilderWizardForm.WizardMode.PerformSelectTablesOnly, out startMode, out settings); 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 ConfigFileUtils.UpdateConfig(settings); // clear all previous errors for this document first ErrorListHelper.ClearErrorsForDocAcrossLists(settings.Artifact.Uri); // log any errors that occurred during model-gen to the error list ErrorListHelper.LogUpdateModelWizardErrors(settings.ModelBuilderEngine.Errors, settings.Artifact.Uri.LocalPath); // 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; } }