/// <summary> /// Changes the s-side Function in the FunctionImportMapping /// </summary> internal void ChangeModelItem(EditingContext context, Function newFunction) { var fi = FunctionImportMapping.FunctionImportName.Target; if (fi != null && FunctionImportMapping.FunctionName.Target != newFunction) { var cModel = EFExtensions.RuntimeModelRoot(FunctionImportMapping.FunctionImportName.Target) as ConceptualEntityModel; if (cModel != null) { var cmd = new ChangeFunctionImportCommand( cModel.FirstEntityContainer as ConceptualEntityContainer, fi, newFunction, fi.LocalName.Value, fi.IsComposable.Value, false, null); // This command can be called before the provider has been registered with the // resolver (e.g. Mapping Details window on a newly-opened project) - so ensure // provider is registered here before any commands are invoked var cpc = new CommandProcessorContext( context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_ChangeFuncImpMapping); VsUtils.EnsureProvider(cpc.Artifact); CommandProcessor.InvokeSingleCommand(cpc, cmd); } } }
public override bool OnDeactivate() { if (Wizard.MovingNext) { var selectedVersion = GetSelectedVersion(); var useLegacyProvider = selectedVersion != null ? RuntimeVersion.RequiresLegacyProvider(selectedVersion) : OptionsDesignerInfo.UseLegacyProviderDefault; if (Wizard.ModelBuilderSettings.UseLegacyProvider != useLegacyProvider) { Wizard.InvalidateFollowingPages(); } Wizard.ModelBuilderSettings.UseLegacyProvider = useLegacyProvider; Wizard.ModelBuilderSettings.TargetSchemaVersion = RuntimeVersion.GetTargetSchemaVersion( selectedVersion, NetFrameworkVersioningHelper.TargetNetFrameworkVersion(Wizard.Project, ServiceProvider)); VsUtils.EnsureProvider( Wizard.ModelBuilderSettings.RuntimeProviderInvariantName, Wizard.ModelBuilderSettings.UseLegacyProvider, Wizard.Project, ServiceProvider); Wizard.ModelBuilderSettings.ProviderManifestToken = VsUtils.GetProviderManifestTokenConnected( DependencyResolver.Instance, Wizard.ModelBuilderSettings.RuntimeProviderInvariantName, Wizard.ModelBuilderSettings.DesignTimeConnectionString); } return(base.OnDeactivate()); }
private static bool ValidateArtifactAndWriteErrors( EFArtifact artifact, IVsHierarchy hierarchy, uint itemId, bool doEscherValidation) { Debug.Assert(artifact != null, "artifact != null!"); Debug.Assert(hierarchy != null, "project hierarchy is null!"); Debug.Assert(itemId != VSConstants.VSITEMID_NIL, "itemid is nil"); var errorList = ErrorListHelper.GetSingleDocErrorList(hierarchy, itemId); Debug.Assert(errorList != null, "Couldn't get error list for artifact " + artifact.Uri); errorList.Clear(); var artifactSet = (EntityDesignArtifactSet)artifact.ArtifactSet; Debug.Assert( artifactSet.Artifacts.OfType <EntityDesignArtifact>().Count() == 1, "Expected there is 1 instance of EntityDesignArtifact; Actual:" + artifactSet.Artifacts.OfType <EntityDesignArtifact>().Count()); VsUtils.EnsureProvider(artifact); ((EntityDesignModelManager)artifact.ModelManager) .ValidateAndCompileMappings(artifactSet, doEscherValidation); var errors = artifactSet.GetArtifactOnlyErrors(artifact); if (errors.Count > 0) { ErrorListHelper.AddErrorInfosToErrorList(errors, hierarchy, itemId, errorList); return(false); } return(true); }
// <summary> // This will do analysis to determine if a document should be opened // only in the XmlEditor. // </summary> internal override void DetermineIfArtifactIsDesignerSafe() { VsUtils.EnsureProvider(this); base.DetermineIfArtifactIsDesignerSafe(); // // TODO: we need to figure out how to deal with errors from the wizard. // when we clear the error list below, we lose errors that we put into the error // list when running the wizard. // // // Now update the VS error list with all of the errors we want to display, which are now in the EFArtifactSet. // var errorInfos = ArtifactSet.GetAllErrors(); if (errorInfos.Count > 0) { var currentProject = VSHelpers.GetProjectForDocument(Uri.LocalPath, PackageManager.Package); if (currentProject != null) { var hierarchy = VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider); if (hierarchy != null) { var fileFinder = new VSFileFinder(Uri.LocalPath); fileFinder.FindInProject(hierarchy); Debug.Assert(fileFinder.MatchingFiles.Count <= 1, "Unexpected count of matching files in project"); // if the EDMX file is not part of the project. if (fileFinder.MatchingFiles.Count == 0) { var docData = VSHelpers.GetDocData(PackageManager.Package, Uri.LocalPath) as IEntityDesignDocData; ErrorListHelper.AddErrorInfosToErrorList(errorInfos, docData.Hierarchy, docData.ItemId); } else { foreach (var vsFileInfo in fileFinder.MatchingFiles) { if (vsFileInfo.Hierarchy == VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider)) { var errorList = ErrorListHelper.GetSingleDocErrorList(vsFileInfo.Hierarchy, vsFileInfo.ItemId); if (errorList != null) { errorList.Clear(); ErrorListHelper.AddErrorInfosToErrorList(errorInfos, vsFileInfo.Hierarchy, vsFileInfo.ItemId); } else { Debug.Fail("errorList is null!"); } } } } } } } }
public void EnsureProvider_unregisters_provider_when_useLegacyProvider() { DependencyResolver.RegisterProvider(typeof(SqlProviderServices), "System.Data.SqlClient"); VsUtils.EnsureProvider("System.Data.SqlClient", true, Mock.Of <Project>(), Mock.Of <IServiceProvider>()); Assert.IsType <LegacyDbProviderServicesWrapper>( DependencyResolver.GetService <DbProviderServices>("System.Data.SqlClient")); }
private static void ValidateArtifact(EntityDesignModelManager modelManager, EFArtifact artifact, WizardKind kind) { var errorsFound = false; Exception caughtException = null; try { VsUtils.EnsureProvider(artifact); var artifactSet = (EntityDesignArtifactSet)modelManager.GetArtifactSet(artifact.Uri); modelManager.ValidateAndCompileMappings(artifactSet, false); // just run the runtime's validation var errors = artifactSet.GetAllErrorsForArtifact(artifact); if (errors != null && errors.Count > 0) { foreach (var error in errors) { if (error.IsError()) { errorsFound = true; break; } } } } catch (Exception e) { caughtException = e; } if (errorsFound || caughtException != null) { var message = string.Empty; if (kind == WizardKind.Generate) { message = Resources.Extensibility_ExtensionMadeBadModel; } else if (kind == WizardKind.UpdateModel) { message = Resources.Extensibility_ExtensionMadeBadModel_Update; } if (caughtException == null) { throw new InvalidOperationException(message); } else { throw new InvalidOperationException(message, caughtException); } } }
public void EnsureProvider_registers_provider_when_not_useLegacyProvider() { VsUtils.EnsureProvider("System.Data.SqlClient", false, Mock.Of <Project>(), Mock.Of <IServiceProvider>()); try { Assert.Same( SqlProviderServices.Instance, DependencyResolver.GetService <DbProviderServices>("System.Data.SqlClient")); } finally { DependencyResolver.UnregisterProvider("System.Data.SqlClient"); } }
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; } }
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(); } } }
// <summary> // Ensure we have the correct provider loaded before we reload // </summary> internal override void ReloadArtifact() { VsUtils.EnsureProvider(this); base.ReloadArtifact(); }
internal static void SetupSettingsAndModeForDbPages( IServiceProvider sp, Project project, EFArtifact artifact, bool checkDatabaseConnection, ModelBuilderWizardForm.WizardMode noConnectionMode, ModelBuilderWizardForm.WizardMode existingConnectionMode, out ModelBuilderWizardForm.WizardMode startMode, out ModelBuilderSettings settings) { var conceptualEntityModel = artifact.ConceptualModel(); Debug.Assert(conceptualEntityModel != null, "Null Conceptual Entity Model"); var entityContainer = conceptualEntityModel.FirstEntityContainer as ConceptualEntityContainer; Debug.Assert(entityContainer != null, "Null Conceptual Entity Container"); var entityContainerName = entityContainer.LocalName.Value; // set up ModelBuilderSettings for startMode=noConnectionMode startMode = noConnectionMode; settings = new ModelBuilderSettings(); var appType = VsUtils.GetApplicationType(sp, project); settings.VSApplicationType = appType; settings.AppConfigConnectionPropertyName = entityContainerName; settings.Artifact = artifact; settings.UseLegacyProvider = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool( OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeUseLegacyProvider, OptionsDesignerInfo.UseLegacyProviderDefault, artifact); settings.TargetSchemaVersion = artifact.SchemaVersion; settings.Project = project; settings.ModelPath = artifact.Uri.LocalPath; // Get the provider manifest token from the existing SSDL. // We don't want to attempt to get it from provider services since this requires a connection // which will severely impact the performance of Model First in disconnected scenarios. settings.ProviderManifestToken = DatabaseGenerationEngine.GetProviderManifestTokenDisconnected(artifact); // Change startMode and settings appropriately depending on whether there is an existing connection string and whether we can/should connect // to the database var connectionString = ConnectionManager.GetConnectionStringObject(project, entityContainerName); if (connectionString != null) { var ecsb = connectionString.Builder; var runtimeProviderName = ecsb.Provider; var runtimeProviderConnectionString = ecsb.ProviderConnectionString; var designTimeProviderConnectionString = connectionString.GetDesignTimeProviderConnectionString(project); var initialCatalog = String.Empty; if (checkDatabaseConnection) { // This path will check to make sure that we can connect to an existing database before changing the start mode to 'existingConnection' IVsDataConnection dataConnection = null; try { var dataConnectionManager = sp.GetService(typeof(IVsDataConnectionManager)) as IVsDataConnectionManager; Debug.Assert(dataConnectionManager != null, "Could not find IVsDataConnectionManager"); var dataProviderManager = sp.GetService(typeof(IVsDataProviderManager)) as IVsDataProviderManager; Debug.Assert(dataProviderManager != null, "Could not find IVsDataProviderManager"); if (dataConnectionManager != null && dataProviderManager != null) { // this will either get an existing connection or attempt to create a new one dataConnection = DataConnectionUtils.GetDataConnection( dataConnectionManager, dataProviderManager, connectionString.DesignTimeProviderInvariantName, designTimeProviderConnectionString); Debug.Assert( dataConnection != null, "Could not find the IVsDataConnection; an exception should have been thrown if this was the case"); if (dataConnection != null) { VsUtils.EnsureProvider(runtimeProviderName, settings.UseLegacyProvider, project, sp); if (CanCreateAndOpenConnection( new StoreSchemaConnectionFactory(), runtimeProviderName, connectionString.DesignTimeProviderInvariantName, designTimeProviderConnectionString)) { startMode = existingConnectionMode; initialCatalog = DataConnectionUtils.GetInitialCatalog(dataProviderManager, dataConnection); } } } } catch { // do nothing - we will go to WizardPageDbConfig which is // what we want if the DB connection fails } finally { // Close the IVsDataConnection if (dataConnection != null) { try { dataConnection.Close(); } catch { } } } } else { // This path will just parse the existing connection string in order to change the start mode. This is ideal for features // that do not need a database connection -- the information in the connection string is enough. startMode = existingConnectionMode; initialCatalog = DataConnectionUtils.GetInitialCatalog( connectionString.DesignTimeProviderInvariantName, designTimeProviderConnectionString); } if (startMode == existingConnectionMode) { // the invariant name and connection string came from app.config, so they are "runtime" invariant names and not "design-time" // (Note: it is OK for InitialCatalog to be null at this stage e.g. from a provider who do not support the concept of Initial Catalog) settings.SetInvariantNamesAndConnectionStrings( project, runtimeProviderName, runtimeProviderConnectionString, runtimeProviderConnectionString, false); settings.InitialCatalog = initialCatalog; settings.AppConfigConnectionPropertyName = entityContainerName; settings.SaveConnectionStringInAppConfig = false; VsUtils.EnsureProvider(runtimeProviderName, settings.UseLegacyProvider, project, sp); } } }