private async Task <bool> ChooseDataBaseConnectionByUiHintAsync(ReverseEngineerOptions options) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var databaseList = vsDataHelper.GetDataConnections(package); if (databaseList != null && databaseList.Any()) { var dataBaseInfo = databaseList.Values.FirstOrDefault(m => m.ConnectionName == options.UiHint); if (dataBaseInfo != null) { options.ConnectionString = dataBaseInfo.ConnectionString; options.DatabaseType = dataBaseInfo.DatabaseType; return(true); } } var dacpacList = await EnvDteExtensions.GetDacpacFilesInActiveSolutionAsync(); if (dacpacList != null && dacpacList.Any() && !string.IsNullOrEmpty(options.UiHint) && options.UiHint.EndsWith(".sqlproj", StringComparison.OrdinalIgnoreCase)) { var candidate = dacpacList .Where(m => !string.IsNullOrWhiteSpace(m) && m.EndsWith(".sqlproj")) .FirstOrDefault(m => m.Equals(options.UiHint, StringComparison.OrdinalIgnoreCase)); if (candidate != null) { options.Dacpac = candidate; return(true); } } return(false); }
private void VerifySQLServerRightsAndVersion(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); if (options.DatabaseType == DatabaseType.SQLServer && string.IsNullOrEmpty(options.Dacpac)) { if (options.ConnectionString.ToLowerInvariant().Contains(".database.windows.net") && options.ConnectionString.ToLowerInvariant().Contains("active directory interactive")) { return; } var rightsAndVersion = reverseEngineerHelper.HasSqlServerViewDefinitionRightsAndVersion(options.ConnectionString); if (rightsAndVersion.Item1 == false) { VSHelper.ShowMessage(ReverseEngineerLocale.SqlServerNoViewDefinitionRights); } if (rightsAndVersion.Item2.Major < 11) { VSHelper.ShowMessage(string.Format(ReverseEngineerLocale.SQLServerVersionNotSupported, rightsAndVersion.Item2)); } } }
private void SaveOptions(Project project, string optionsPath, ReverseEngineerOptions options, Tuple <List <Schema>, string> renamingOptions) { ThreadHelper.ThrowIfNotOnUIThread(); if (File.Exists(optionsPath) && File.GetAttributes(optionsPath).HasFlag(FileAttributes.ReadOnly)) { EnvDteHelper.ShowError($"Unable to save options, the file is readonly: {optionsPath}"); return; } if (!File.Exists(optionsPath + ".ignore")) { File.WriteAllText(optionsPath, options.Write(), Encoding.UTF8); project.ProjectItems.AddFromFile(optionsPath); } if (renamingOptions.Item1 != null && !File.Exists(renamingOptions.Item2 + ".ignore") && renamingOptions.Item1.Count() > 0) { if (File.Exists(renamingOptions.Item2) && File.GetAttributes(renamingOptions.Item2).HasFlag(FileAttributes.ReadOnly)) { EnvDteHelper.ShowError($"Unable to save renaming options, the file is readonly: {renamingOptions.Item2}"); return; } File.WriteAllText(renamingOptions.Item2, CustomNameOptionsExtensions.Write(renamingOptions.Item1), Encoding.UTF8); project.ProjectItems.AddFromFile(renamingOptions.Item2); } }
private async Task <bool> LoadDataBaseObjectsAsync(ReverseEngineerOptions options, DatabaseInfo dbInfo, Tuple <List <Schema>, string> namingOptionsAndPath) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); _package.Dte2.StatusBar.Animate(true, _icon); var predefinedTables = !string.IsNullOrEmpty(options.Dacpac) ? await GetDacpacTablesAsync(options.Dacpac, options.CodeGenerationMode == CodeGenerationMode.EFCore5) : await GetTablesAsync(dbInfo, options.CodeGenerationMode == CodeGenerationMode.EFCore5, options.Schemas?.ToArray()); _package.Dte2.StatusBar.Animate(false, _icon); var preselectedTables = new List <SerializationTableModel>(); if (options.Tables?.Count > 0) { var normalizedTables = reverseEngineerHelper.NormalizeTables(options.Tables, dbInfo.DatabaseType == DatabaseType.SQLServer); preselectedTables.AddRange(normalizedTables); } _package.Dte2.StatusBar.Clear(); var ptd = _package.GetView <IPickTablesDialog>() .AddTables(predefinedTables, namingOptionsAndPath.Item1) .PreselectTables(preselectedTables); var pickTablesResult = ptd.ShowAndAwaitUserResponse(true); options.Tables = pickTablesResult.Payload.Objects.ToList(); options.CustomReplacers = pickTablesResult.Payload.CustomReplacers.ToList(); return(pickTablesResult.ClosedByOK); }
private DatabaseConnectionModel GetDatabaseInfo(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); var dbInfo = new DatabaseConnectionModel(); if (!string.IsNullOrEmpty(options.ConnectionString)) { dbInfo.ConnectionString = options.ConnectionString; dbInfo.DatabaseType = options.DatabaseType; } if (!string.IsNullOrEmpty(options.Dacpac)) { dbInfo.DatabaseType = DatabaseType.SQLServerDacpac; dbInfo.ConnectionString = $"Data Source=(local);Initial Catalog={Path.GetFileNameWithoutExtension(options.Dacpac)};Integrated Security=true;"; options.ConnectionString = dbInfo.ConnectionString; options.DatabaseType = dbInfo.DatabaseType; options.Dacpac = _package.Dte2.DTE.BuildSqlProj(options.Dacpac); if (string.IsNullOrEmpty(options.Dacpac)) { EnvDteHelper.ShowMessage(ReverseEngineerLocale.UnableToBuildSelectedDatabaseProject); return(null); } } if (dbInfo.DatabaseType == DatabaseType.Undefined) { EnvDteHelper.ShowError($"{ReverseEngineerLocale.UnsupportedProvider}"); return(null); } return(dbInfo); }
private async Task <bool> ChooseDataBaseConnectionAsync(ReverseEngineerOptions options) { var databaseList = vsDataHelper.GetDataConnections(_package); var dacpacList = await EnvDTEExtensions.GetDacpacFilesInActiveSolutionAsync(); var psd = _package.GetView <IPickServerDatabaseDialog>(); if (databaseList != null && databaseList.Any()) { psd.PublishConnections(databaseList.Select(m => new DatabaseConnectionModel { ConnectionName = m.Value.ConnectionName, ConnectionString = m.Value.ConnectionString, DatabaseType = m.Value.DatabaseType, DataConnection = m.Value.DataConnection, })); } if (dacpacList != null && dacpacList.Any()) { psd.PublishDefinitions(dacpacList.Select(m => new DatabaseDefinitionModel { FilePath = m })); } if (options.FilterSchemas && options.Schemas != null && options.Schemas.Any()) { psd.PublishSchemas(options.Schemas); } psd.PublishCodeGenerationMode(options.CodeGenerationMode); if (!string.IsNullOrEmpty(options.UiHint)) { psd.PublishUiHint(options.UiHint); } var pickDataSourceResult = psd.ShowAndAwaitUserResponse(true); if (!pickDataSourceResult.ClosedByOK) { return(false); } options.CodeGenerationMode = pickDataSourceResult.Payload.CodeGenerationMode; options.FilterSchemas = pickDataSourceResult.Payload.FilterSchemas; options.Schemas = options.FilterSchemas ? pickDataSourceResult.Payload.Schemas?.ToList() : null; options.UiHint = pickDataSourceResult.Payload.UiHint; options.Dacpac = pickDataSourceResult.Payload.Definition?.FilePath; if (pickDataSourceResult.Payload.Connection != null) { options.ConnectionString = pickDataSourceResult.Payload.Connection.ConnectionString; options.DatabaseType = pickDataSourceResult.Payload.Connection.DatabaseType; } return(true); }
public static async Task <ReverseEngineerResult> LaunchExternalRunnerAsync(ReverseEngineerOptions options, CodeGenerationMode codeGenerationMode, Project project) { var databaseObjects = options.Tables; if (!databaseObjects.Any(t => t.ObjectType == ObjectType.Table)) { // No tables selected, so add a dummy table in order to generate an empty DbContext databaseObjects.Add(new SerializationTableModel($"Dummy_{new Guid(GuidList.guidDbContextPackagePkgString)}", ObjectType.Table, null)); } var commandOptions = new ReverseEngineerCommandOptions { ConnectionString = options.ConnectionString, ContextClassName = options.ContextClassName, CustomReplacers = options.CustomReplacers, Dacpac = options.Dacpac, DatabaseType = options.DatabaseType, DefaultDacpacSchema = options.DefaultDacpacSchema, IncludeConnectionString = options.IncludeConnectionString, OutputPath = options.OutputPath, ContextNamespace = options.ContextNamespace, ModelNamespace = options.ModelNamespace, OutputContextPath = options.OutputContextPath, UseSchemaFolders = options.UseSchemaFolders, ProjectPath = options.ProjectPath, ProjectRootNamespace = options.ProjectRootNamespace, SelectedHandlebarsLanguage = options.SelectedHandlebarsLanguage, SelectedToBeGenerated = options.SelectedToBeGenerated, Tables = databaseObjects, UseDatabaseNames = options.UseDatabaseNames, UseFluentApiOnly = options.UseFluentApiOnly, UseHandleBars = options.UseHandleBars, UseInflector = options.UseInflector, UseLegacyPluralizer = options.UseLegacyPluralizer, UseSpatial = options.UseSpatial, UseHierarchyId = options.UseHierarchyId, UseDbContextSplitting = options.UseDbContextSplitting, UseNodaTime = options.UseNodaTime, UseBoolPropertiesWithoutDefaultSql = options.UseBoolPropertiesWithoutDefaultSql, UseNullableReferences = options.UseNullableReferences, UseNoConstructor = options.UseNoConstructor, UseNoNavigations = options.UseNoNavigations, UseNoObjectFilter = options.UseNoObjectFilter, UseNoDefaultConstructor = options.UseNoDefaultConstructor, UseManyToManyEntity = options.UseManyToManyEntity, RunCleanup = AdvancedOptions.Instance.RunCleanup, UseMultipleSprocResultSets = AdvancedOptions.Instance.DiscoverMultipleResultSets, OptionsPath = options.OptionsPath, LegacyLangVersion = await project.IsLegacyAsync(), MergeDacpacs = AdvancedOptions.Instance.MergeDacpacs, UseLegacyResultSetDiscovery = AdvancedOptions.Instance.UseLegacyResultSetDiscovery, UseAsyncCalls = AdvancedOptions.Instance.PreferAsyncCalls, }; var launcher = new EfRevEngLauncher(commandOptions, codeGenerationMode); return(await launcher.GetOutputAsync()); }
private async Task <bool> SetNullableAsync(ReverseEngineerOptions options, Project project) { var nullable = await project.GetAttributeAsync("Nullable"); if (string.Equals(nullable, "enable", StringComparison.OrdinalIgnoreCase) || string.Equals(nullable, "annotations", StringComparison.OrdinalIgnoreCase)) { return(true); } return(await project.IsNetFrameworkAsync() ? false : options.UseNullableReferences); }
public static async Task <ReverseEngineerResult> LaunchExternalRunnerAsync(ReverseEngineerOptions options, CodeGenerationMode codeGenerationMode) { var databaseObjects = options.Tables; if (databaseObjects.Where(t => t.ObjectType == ObjectType.Table).Count() == 0) { // No tables selected, so add a dummy table in order to generate an empty DbContext databaseObjects.Add(new SerializationTableModel($"Dummy_{new Guid(GuidList.guidDbContextPackagePkgString)}", ObjectType.Table, null)); } var commandOptions = new ReverseEngineerCommandOptions { ConnectionString = options.ConnectionString, ContextClassName = options.ContextClassName, CustomReplacers = options.CustomReplacers, Dacpac = options.Dacpac, DatabaseType = options.DatabaseType, DefaultDacpacSchema = options.DefaultDacpacSchema, IncludeConnectionString = options.IncludeConnectionString, OutputPath = options.OutputPath, ContextNamespace = options.ContextNamespace, ModelNamespace = options.ModelNamespace, OutputContextPath = options.OutputContextPath, UseSchemaFolders = options.UseSchemaFolders, ProjectPath = options.ProjectPath, ProjectRootNamespace = options.ProjectRootNamespace, SelectedHandlebarsLanguage = options.SelectedHandlebarsLanguage, SelectedToBeGenerated = options.SelectedToBeGenerated, Tables = databaseObjects, UseDatabaseNames = options.UseDatabaseNames, UseFluentApiOnly = options.UseFluentApiOnly, UseHandleBars = options.UseHandleBars, UseInflector = options.UseInflector, UseLegacyPluralizer = options.UseLegacyPluralizer, UseSpatial = options.UseSpatial, UseDbContextSplitting = options.UseDbContextSplitting, UseNodaTime = options.UseNodaTime, UseBoolPropertiesWithoutDefaultSql = options.UseBoolPropertiesWithoutDefaultSql, UseNullableReferences = options.UseNullableReferences, UseNoConstructor = options.UseNoConstructor, UseNoNavigations = options.UseNoNavigations, UseNoObjectFilter = options.UseNoObjectFilter, UseNoDefaultConstructor = options.UseNoDefaultConstructor, }; var launcher = new EfRevEngLauncher(commandOptions, codeGenerationMode); return(await launcher.GetOutputAsync()); }
private void SaveOptions(Project project, string optionsPath, ReverseEngineerOptions options, Tuple <List <Schema>, string> renamingOptions) { ThreadHelper.ThrowIfNotOnUIThread(); if (!File.Exists(optionsPath + ".ignore")) { File.WriteAllText(optionsPath, options.Write(), Encoding.UTF8); project.ProjectItems.AddFromFile(optionsPath); } if (renamingOptions.Item1 != null && !File.Exists(renamingOptions.Item2 + ".ignore") && renamingOptions.Item1.Count() > 0) { File.WriteAllText(renamingOptions.Item2, CustomNameOptionsExtensions.Write(renamingOptions.Item1), Encoding.UTF8); project.ProjectItems.AddFromFile(renamingOptions.Item2); } }
private bool ChooseDataBaseConnectionByUiHint(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); var databaseList = vsDataHelper.GetDataConnections(_package); if (databaseList != null && databaseList.Any()) { var dataBaseInfo = databaseList.Values.FirstOrDefault(m => m.Caption == options.UiHint); if (dataBaseInfo != null) { options.ConnectionString = dataBaseInfo.ConnectionString; options.DatabaseType = dataBaseInfo.DatabaseType; return(true); } } return(false); }
private void VerifySQLServerRightsAndVersion(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); if (options.DatabaseType == DatabaseType.SQLServer && string.IsNullOrEmpty(options.Dacpac)) { var rightsAndVersion = reverseEngineerHelper.HasSqlServerViewDefinitionRightsAndVersion(options.ConnectionString); if (rightsAndVersion.Item1 == false) { EnvDteHelper.ShowMessage("The SQL Server user does not have 'VIEW DEFINITION' rights, default constraints may not be available."); } if (rightsAndVersion.Item2.Major < 11) { EnvDteHelper.ShowMessage($"SQL Server version {rightsAndVersion.Item2} may not be supported."); } } }
private void VerifySQLServerRightsAndVersion(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); if (options.DatabaseType == DatabaseType.SQLServer && string.IsNullOrEmpty(options.Dacpac)) { var rightsAndVersion = reverseEngineerHelper.HasSqlServerViewDefinitionRightsAndVersion(options.ConnectionString); if (rightsAndVersion.Item1 == false) { EnvDteHelper.ShowMessage(ReverseEngineerLocale.SqlServerNoViewDefinitionRights); } if (rightsAndVersion.Item2.Major < 11) { EnvDteHelper.ShowMessage(String.Format(ReverseEngineerLocale.SQLServerVersionNotSupported, rightsAndVersion.Item2)); } } }
private DatabaseInfo GetDatabaseInfo(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); DatabaseInfo dbInfo = new DatabaseInfo(); if (!string.IsNullOrEmpty(options.ConnectionString)) { dbInfo.ConnectionString = options.ConnectionString; dbInfo.DatabaseType = options.DatabaseType; } if (!string.IsNullOrEmpty(options.Dacpac)) { dbInfo.DatabaseType = DatabaseType.SQLServerDacpac; if (options.Dacpac.EndsWith(".edmx", StringComparison.OrdinalIgnoreCase)) { dbInfo.DatabaseType = DatabaseType.Edmx; } dbInfo.ConnectionString = $"Data Source=(local);Initial Catalog={Path.GetFileNameWithoutExtension(options.Dacpac)};Integrated Security=true;"; options.ConnectionString = dbInfo.ConnectionString; options.DatabaseType = dbInfo.DatabaseType; options.Dacpac = _package.Dte2.DTE.BuildSqlProj(options.Dacpac); if (string.IsNullOrEmpty(options.Dacpac)) { EnvDteHelper.ShowMessage(ReverseEngineerLocale.UnableToBuildSelectedDatabaseProject); return(null); } } if (dbInfo.DatabaseType == DatabaseType.SQLCE35 || dbInfo.DatabaseType == DatabaseType.SQLCE40 || dbInfo.DatabaseType == DatabaseType.Undefined) { EnvDteHelper.ShowError($"{ReverseEngineerLocale.UnsupportedProvider}: {dbInfo.ServerVersion}"); return(null); } return(dbInfo); }
public static async Task <ReverseEngineerResult> LaunchExternalRunnerAsync(ReverseEngineerOptions options, CodeGenerationMode codeGenerationMode) { var commandOptions = new ReverseEngineerCommandOptions { ConnectionString = options.ConnectionString, ContextClassName = options.ContextClassName, CustomReplacers = options.CustomReplacers, Dacpac = options.Dacpac, DatabaseType = options.DatabaseType, DefaultDacpacSchema = options.DefaultDacpacSchema, IncludeConnectionString = options.IncludeConnectionString, OutputPath = options.OutputPath, ContextNamespace = options.ContextNamespace, ModelNamespace = options.ModelNamespace, OutputContextPath = options.OutputContextPath, UseSchemaFolders = options.UseSchemaFolders, ProjectPath = options.ProjectPath, ProjectRootNamespace = options.ProjectRootNamespace, SelectedHandlebarsLanguage = options.SelectedHandlebarsLanguage, SelectedToBeGenerated = options.SelectedToBeGenerated, Tables = options.Tables, UseDatabaseNames = options.UseDatabaseNames, UseFluentApiOnly = options.UseFluentApiOnly, UseHandleBars = options.UseHandleBars, UseInflector = options.UseInflector, UseLegacyPluralizer = options.UseLegacyPluralizer, UseSpatial = options.UseSpatial, UseDbContextSplitting = options.UseDbContextSplitting, UseNodaTime = options.UseNodaTime, UseBoolPropertiesWithoutDefaultSql = options.UseBoolPropertiesWithoutDefaultSql, UseNullableReferences = options.UseNullableReferences, UseNoConstructor = options.UseNoConstructor, UseNoNavigations = options.UseNoNavigations, UseNoObjectFilter = options.UseNoObjectFilter, }; var launcher = new EfRevEngLauncher(commandOptions, codeGenerationMode); return(await launcher.GetOutputAsync()); }
private bool ChooseDataBaseConnectionByUiHint(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); var databaseList = vsDataHelper.GetDataConnections(_package); if (databaseList != null && databaseList.Any()) { var dataBaseInfo = databaseList.Values.FirstOrDefault(m => m.ConnectionName == options.UiHint); if (dataBaseInfo != null) { options.ConnectionString = dataBaseInfo.ConnectionString; options.DatabaseType = dataBaseInfo.DatabaseType; return(true); } } var dacpacList = _package.Dte2.DTE.GetDacpacFilesInActiveSolution(EnvDteHelper.GetProjectFilesInSolution(_package)); if (dacpacList != null && dacpacList.Any()) { if (!string.IsNullOrEmpty(options.UiHint) && options.UiHint.EndsWith(".sqlproj", StringComparison.OrdinalIgnoreCase)) { var candidate = dacpacList .Where(m => !string.IsNullOrWhiteSpace(m) && m.EndsWith(".sqlproj")) .FirstOrDefault(m => m.Equals(options.UiHint, StringComparison.OrdinalIgnoreCase)); if (candidate != null) { options.Dacpac = candidate; return(true); } } } return(false); }
private async Task <DatabaseConnectionModel> GetDatabaseInfoAsync(ReverseEngineerOptions options) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var dbInfo = new DatabaseConnectionModel(); if (!string.IsNullOrEmpty(options.ConnectionString)) { dbInfo.ConnectionString = options.ConnectionString; dbInfo.DatabaseType = options.DatabaseType; } if (!string.IsNullOrEmpty(options.Dacpac)) { dbInfo.DatabaseType = DatabaseType.SQLServerDacpac; dbInfo.ConnectionString = $"Data Source=(local);Initial Catalog={Path.GetFileNameWithoutExtension(options.Dacpac)};Integrated Security=true;"; options.ConnectionString = dbInfo.ConnectionString; options.DatabaseType = dbInfo.DatabaseType; options.Dacpac = await EnvDTEExtensions.BuildSqlProjAsync(options.Dacpac); if (string.IsNullOrEmpty(options.Dacpac)) { VSHelper.ShowMessage(ReverseEngineerLocale.UnableToBuildSelectedDatabaseProject); return(null); } } if (dbInfo.DatabaseType == DatabaseType.Undefined) { VSHelper.ShowError($"{ReverseEngineerLocale.UnsupportedProvider}"); return(null); } return(dbInfo); }
private static async System.Threading.Tasks.Task InstallNuGetPackagesAsync(Project project, bool onlyGenerate, Tuple <bool, string> containsEfCoreReference, ReverseEngineerOptions options, bool forceEdit) { var nuGetHelper = new NuGetHelper(); if (options.InstallNuGetPackage && (!onlyGenerate || forceEdit) && await project.IsNetCore31OrHigherAsync() && containsEfCoreReference != null) { await VS.StatusBar.ShowMessageAsync(ReverseEngineerLocale.InstallingEFCoreProviderPackage); await nuGetHelper.InstallPackageAsync(containsEfCoreReference.Item2, project); } if (options.Tables.Any(t => t.ObjectType == ObjectType.Procedure) && AdvancedOptions.Instance.DiscoverMultipleResultSets) { await nuGetHelper.InstallPackageAsync("Dapper", project); } }
private bool ChooseDataBaseConnection(ReverseEngineerOptions options) { ThreadHelper.ThrowIfNotOnUIThread(); var databaseList = vsDataHelper.GetDataConnections(_package); var dacpacList = _package.Dte2.DTE.GetDacpacFilesInActiveSolution(EnvDteHelper.GetProjectFilesInSolution(_package)); var psd = _package.GetView <IPickServerDatabaseDialog>(); if (databaseList != null && databaseList.Any()) { psd.PublishConnections(databaseList.Select(m => new DatabaseConnectionModel { ConnectionName = m.Value.Caption, ConnectionString = m.Value.ConnectionString, DatabaseType = m.Value.DatabaseType, DataConnection = m.Value.DataConnection, })); } if (dacpacList != null && dacpacList.Any()) { psd.PublishDefinitions(dacpacList.Select(m => new DatabaseDefinitionModel { FilePath = m })); } if (options.FilterSchemas && options.Schemas != null && options.Schemas.Any()) { psd.PublishSchemas(options.Schemas); } psd.PublishCodeGenerationMode(options.CodeGenerationMode); if (!string.IsNullOrEmpty(options.UiHint)) { psd.PublishUiHint(options.UiHint); } var pickDataSourceResult = psd.ShowAndAwaitUserResponse(true); if (!pickDataSourceResult.ClosedByOK) { return(false); } options.CodeGenerationMode = pickDataSourceResult.Payload.IncludeViews ? CodeGenerationMode.EFCore5 : CodeGenerationMode.EFCore3; options.FilterSchemas = pickDataSourceResult.Payload.FilterSchemas; options.Schemas = options.FilterSchemas ? pickDataSourceResult.Payload.Schemas?.ToList() : null; options.UiHint = pickDataSourceResult.Payload.UiHint; options.Dacpac = pickDataSourceResult.Payload.Definition?.FilePath; if (pickDataSourceResult.Payload.Connection != null) { options.ConnectionString = pickDataSourceResult.Payload.Connection.ConnectionString; options.DatabaseType = pickDataSourceResult.Payload.Connection.DatabaseType; } return(true); }
public async System.Threading.Tasks.Task ReverseEngineerCodeFirstAsync(Project project, string optionsPath, bool onlyGenerate) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); try { if (await VSHelper.IsDebugModeAsync()) { VSHelper.ShowError(ReverseEngineerLocale.CannotGenerateCodeWhileDebugging); return; } var renamingPath = project.GetRenamingPath(optionsPath); var namingOptionsAndPath = CustomNameOptionsExtensions.TryRead(renamingPath, optionsPath); Tuple <bool, string> containsEfCoreReference = null; var options = ReverseEngineerOptionsExtensions.TryRead(optionsPath, Path.GetDirectoryName(project.FullPath)); if (options == null) { options = new ReverseEngineerOptions { ProjectRootNamespace = await project.GetAttributeAsync("RootNamespace"), }; } legacyDiscoveryObjects = options.Tables?.Where(t => t.UseLegacyResultSetDiscovery).Select(t => t.Name).ToList() ?? new List <string>(); mappedTypes = options.Tables? .Where(t => !string.IsNullOrEmpty(t.MappedType) && t.ObjectType == ObjectType.Procedure) .Select(m => new { m.Name, m.MappedType }).ToDictionary(m => m.Name, m => m.MappedType) ?? new Dictionary <string, string>(); options.ProjectPath = Path.GetDirectoryName(project.FullPath); options.OptionsPath = Path.GetDirectoryName(optionsPath); bool forceEdit = false; if (onlyGenerate) { forceEdit = !await ChooseDataBaseConnectionByUiHintAsync(options); if (forceEdit) { await VS.StatusBar.ShowMessageAsync(ReverseEngineerLocale.DatabaseConnectionNotFoundCannotRefresh); } else { var dbInfo = await GetDatabaseInfoAsync(options); if (dbInfo == null) { return; } containsEfCoreReference = new Tuple <bool, string>(true, null); options.CustomReplacers = namingOptionsAndPath.Item1; options.InstallNuGetPackage = false; } } if (!onlyGenerate || forceEdit) { if (!await ChooseDataBaseConnectionAsync(options)) { return; } await VS.StatusBar.ShowMessageAsync(ReverseEngineerLocale.GettingReadyToConnect); var dbInfo = await GetDatabaseInfoAsync(options); if (dbInfo == null) { return; } VerifySQLServerRightsAndVersion(options); await VS.StatusBar.ShowMessageAsync(ReverseEngineerLocale.LoadingDatabaseObjects); if (!await LoadDataBaseObjectsAsync(options, dbInfo, namingOptionsAndPath)) { return; } await VS.StatusBar.ShowMessageAsync(ReverseEngineerLocale.LoadingOptions); containsEfCoreReference = await project.ContainsEfCoreReferenceAsync(options.DatabaseType); options.InstallNuGetPackage = !containsEfCoreReference.Item1; if (!await GetModelOptionsAsync(options, project.Name)) { return; } await SaveOptionsAsync(project, optionsPath, options, new Tuple <List <Schema>, string>(options.CustomReplacers, namingOptionsAndPath.Item2)); } await GenerateFilesAsync(project, options, containsEfCoreReference); await InstallNuGetPackagesAsync(project, onlyGenerate, containsEfCoreReference, options, forceEdit); var postRunFile = Path.Combine(Path.GetDirectoryName(optionsPath), "efpt.postrun.cmd"); if (File.Exists(postRunFile)) { Process.Start($"\"{postRunFile}\""); } Telemetry.TrackEvent("PowerTools.ReverseEngineer"); } catch (AggregateException ae) { foreach (var innerException in ae.Flatten().InnerExceptions) { package.LogError(new List <string>(), innerException); } } catch (Exception exception) { package.LogError(new List <string>(), exception); } }
public async System.Threading.Tasks.Task ReverseEngineerCodeFirstAsync(Project project, string optionsPath, bool onlyGenerate) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); try { var dteH = new EnvDteHelper(); if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug) { EnvDteHelper.ShowError(ReverseEngineerLocale.CannotGenerateCodeWhileDebugging); return; } var renamingPath = project.GetRenamingPath(optionsPath); var namingOptionsAndPath = CustomNameOptionsExtensions.TryRead(renamingPath, optionsPath); Tuple <bool, string> containsEfCoreReference = null; var options = ReverseEngineerOptionsExtensions.TryRead(optionsPath); if (options == null) { options = new ReverseEngineerOptions { ProjectRootNamespace = project.Properties.Item("DefaultNamespace").Value.ToString() }; } options.ProjectPath = project.Properties.Item("FullPath")?.Value.ToString(); bool forceEdit = false; if (onlyGenerate) { forceEdit = !ChooseDataBaseConnectionByUiHint(options); if (forceEdit) { _package.Dte2.StatusBar.Text = ReverseEngineerLocale.DatabaseConnectionNotFoundCannotRefresh; } else { var dbInfo = GetDatabaseInfo(options); if (dbInfo == null) { return; } containsEfCoreReference = new Tuple <bool, string>(true, null); options.CustomReplacers = namingOptionsAndPath.Item1; options.InstallNuGetPackage = false; } } if (!onlyGenerate || forceEdit) { if (!ChooseDataBaseConnection(options)) { return; } _package.Dte2.StatusBar.Text = ReverseEngineerLocale.GettingReadyToConnect; var dbInfo = GetDatabaseInfo(options); if (dbInfo == null) { return; } _package.Dte2.StatusBar.Text = ReverseEngineerLocale.LoadingDatabaseObjects; if (!await LoadDataBaseObjectsAsync(options, dbInfo, namingOptionsAndPath)) { return; } _package.Dte2.StatusBar.Text = ReverseEngineerLocale.LoadingOptions; containsEfCoreReference = project.ContainsEfCoreReference(options.DatabaseType); options.InstallNuGetPackage = !containsEfCoreReference.Item1; if (!GetModelOptions(options, project.Name)) { return; } SaveOptions(project, optionsPath, options, new Tuple <List <Schema>, string>(options.CustomReplacers, namingOptionsAndPath.Item2)); } VerifySQLServerRightsAndVersion(options); await GenerateFilesAsync(project, options, containsEfCoreReference); if (options.InstallNuGetPackage && (!onlyGenerate || forceEdit) && project.IsNetCore31OrHigher()) { _package.Dte2.StatusBar.Text = ReverseEngineerLocale.InstallingEFCoreProviderPackage; var nuGetHelper = new NuGetHelper(); await nuGetHelper.InstallPackageAsync(containsEfCoreReference.Item2, project); } Telemetry.TrackEvent("PowerTools.ReverseEngineer"); } catch (AggregateException ae) { foreach (var innerException in ae.Flatten().InnerExceptions) { _package.LogError(new List <string>(), innerException); } } catch (Exception exception) { _package.LogError(new List <string>(), exception); } }
private async System.Threading.Tasks.Task GenerateFilesAsync(Project project, ReverseEngineerOptions options, Tuple <bool, string> containsEfCoreReference) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var startTime = DateTime.Now; if (options.UseHandleBars) { var dropped = (DropTemplates(options.ProjectPath, options.CodeGenerationMode == CodeGenerationMode.EFCore5)); if (dropped) { project.ProjectItems.AddFromDirectory(Path.Combine(options.ProjectPath, "CodeTemplates")); } } options.UseNullableReferences = project.IsNetFramework() ? false : options.UseNullableReferences; _package.Dte2.StatusBar.Animate(true, _icon); _package.Dte2.StatusBar.Text = ReverseEngineerLocale.GeneratingCode; var revEngResult = await EfRevEngLauncher.LaunchExternalRunnerAsync(options, options.CodeGenerationMode); _package.Dte2.StatusBar.Animate(false, _icon); var tfm = project.Properties.Item("TargetFrameworkMoniker").Value.ToString(); bool isNetStandard = tfm.Contains(".NETStandard,Version=v2."); if (options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 2) { if (!project.IsNetCore31OrHigher() && !isNetStandard) { foreach (var filePath in revEngResult.EntityTypeFilePaths) { project.ProjectItems.AddFromFile(filePath); } } } if (options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 1) { if (!project.IsNetCore31OrHigher() && !isNetStandard) { foreach (var filePath in revEngResult.ContextConfigurationFilePaths) { project.ProjectItems.AddFromFile(filePath); } project.ProjectItems.AddFromFile(revEngResult.ContextFilePath); } _package.Dte2.ItemOperations.OpenFile(revEngResult.ContextFilePath); } var duration = DateTime.Now - startTime; var missingProviderPackage = containsEfCoreReference.Item1 ? null : containsEfCoreReference.Item2; if (options.InstallNuGetPackage || options.SelectedToBeGenerated == 2) { missingProviderPackage = null; } _package.Dte2.StatusBar.Text = ReverseEngineerLocale.ReportingResult; var errors = reverseEngineerHelper.ReportRevEngErrors(revEngResult, missingProviderPackage); _package.Dte2.StatusBar.Text = String.Format(ReverseEngineerLocale.ReverseEngineerCompleted, duration.ToString("h\\:mm\\:ss")); EnvDteHelper.ShowMessage(errors); if (revEngResult.EntityErrors.Count > 0) { _package.LogError(revEngResult.EntityErrors, null); } if (revEngResult.EntityWarnings.Count > 0) { _package.LogError(revEngResult.EntityWarnings, null); } }
private async System.Threading.Tasks.Task SaveOptionsAsync(Project project, string optionsPath, ReverseEngineerOptions options, Tuple <List <Schema>, string> renamingOptions) { if (File.Exists(optionsPath) && File.GetAttributes(optionsPath).HasFlag(FileAttributes.ReadOnly)) { VSHelper.ShowError($"Unable to save options, the file is readonly: {optionsPath}"); return; } if (!File.Exists(optionsPath + ".ignore")) { if (!AdvancedOptions.Instance.IncludeUiHintInConfig) { options.UiHint = null; } foreach (var table in options.Tables) { if (legacyDiscoveryObjects.Contains(table.Name)) { table.UseLegacyResultSetDiscovery = true; } if (mappedTypes.ContainsKey(table.Name)) { table.MappedType = mappedTypes[table.Name]; } } File.WriteAllText(optionsPath, options.Write(Path.GetDirectoryName(project.FullPath)), Encoding.UTF8); await project.AddExistingFilesAsync(new List <string> { optionsPath }.ToArray()); } if (renamingOptions.Item1 != null && !File.Exists(renamingOptions.Item2 + ".ignore") && renamingOptions.Item1.Count > 0) { if (File.Exists(renamingOptions.Item2) && File.GetAttributes(renamingOptions.Item2).HasFlag(FileAttributes.ReadOnly)) { VSHelper.ShowError($"Unable to save renaming options, the file is readonly: {renamingOptions.Item2}"); return; } File.WriteAllText(renamingOptions.Item2, CustomNameOptionsExtensions.Write(renamingOptions.Item1), Encoding.UTF8); await project.AddExistingFilesAsync(new List <string> { renamingOptions.Item2 }.ToArray()); } }
private bool GetModelOptions(ReverseEngineerOptions options, string projectName) { ThreadHelper.ThrowIfNotOnUIThread(); var classBasis = VsDataHelper.GetDatabaseName(options.ConnectionString, options.DatabaseType); var model = reverseEngineerHelper.GenerateClassName(classBasis) + "Context"; if (string.IsNullOrEmpty(options.ContextClassName)) { options.ContextClassName = model; } var presets = new ModelingOptionsModel { InstallNuGetPackage = options.InstallNuGetPackage, ModelName = options.ContextClassName, ProjectName = projectName, Namespace = options.ProjectRootNamespace, DacpacPath = options.Dacpac, UseDataAnnotations = !options.UseFluentApiOnly, UseDatabaseNames = options.UseDatabaseNames, UsePluralizer = options.UseInflector, UseDbContextSplitting = options.UseDbContextSplitting, UseHandlebars = options.UseHandleBars, SelectedHandlebarsLanguage = options.SelectedHandlebarsLanguage, IncludeConnectionString = options.IncludeConnectionString, OutputPath = options.OutputPath, OutputContextPath = options.OutputContextPath, ModelNamespace = options.ModelNamespace, ContextNamespace = options.ContextNamespace, SelectedToBeGenerated = options.SelectedToBeGenerated, UseEf6Pluralizer = options.UseLegacyPluralizer, MapSpatialTypes = options.UseSpatial, MapNodaTimeTypes = options.UseNodaTime, UseBoolPropertiesWithoutDefaultSql = options.UseBoolPropertiesWithoutDefaultSql, UseNoConstructor = options.UseNoConstructor, UseNoNavigations = options.UseNoNavigations, UseNullableReferences = options.UseNullableReferences, UseNoObjectFilter = options.UseNoObjectFilter, }; var modelDialog = _package.GetView <IModelingOptionsDialog>() .ApplyPresets(presets); _package.Dte2.StatusBar.Clear(); var modelingOptionsResult = modelDialog.ShowAndAwaitUserResponse(true); if (!modelingOptionsResult.ClosedByOK) { return(false); } options.InstallNuGetPackage = modelingOptionsResult.Payload.InstallNuGetPackage; options.UseFluentApiOnly = !modelingOptionsResult.Payload.UseDataAnnotations; options.ContextClassName = modelingOptionsResult.Payload.ModelName; options.OutputPath = modelingOptionsResult.Payload.OutputPath; options.OutputContextPath = modelingOptionsResult.Payload.OutputContextPath; options.ContextNamespace = modelingOptionsResult.Payload.ContextNamespace; options.ModelNamespace = modelingOptionsResult.Payload.ModelNamespace; options.ProjectRootNamespace = modelingOptionsResult.Payload.Namespace; options.UseDatabaseNames = modelingOptionsResult.Payload.UseDatabaseNames; options.UseInflector = modelingOptionsResult.Payload.UsePluralizer; options.UseLegacyPluralizer = modelingOptionsResult.Payload.UseEf6Pluralizer; options.UseSpatial = modelingOptionsResult.Payload.MapSpatialTypes; options.UseNodaTime = modelingOptionsResult.Payload.MapNodaTimeTypes; options.UseDbContextSplitting = modelingOptionsResult.Payload.UseDbContextSplitting; options.UseHandleBars = modelingOptionsResult.Payload.UseHandlebars; options.SelectedHandlebarsLanguage = modelingOptionsResult.Payload.SelectedHandlebarsLanguage; options.IncludeConnectionString = modelingOptionsResult.Payload.IncludeConnectionString; options.SelectedToBeGenerated = modelingOptionsResult.Payload.SelectedToBeGenerated; options.UseBoolPropertiesWithoutDefaultSql = modelingOptionsResult.Payload.UseBoolPropertiesWithoutDefaultSql; options.UseNullableReferences = modelingOptionsResult.Payload.UseNullableReferences; options.UseNoConstructor = modelingOptionsResult.Payload.UseNoConstructor; options.UseNoNavigations = modelingOptionsResult.Payload.UseNoNavigations; options.UseNoObjectFilter = modelingOptionsResult.Payload.UseNoObjectFilter; return(true); }
private void GenerateFiles(Project project, ReverseEngineerOptions options, Tuple <bool, string> containsEfCoreReference) { ThreadHelper.ThrowIfNotOnUIThread(); var startTime = DateTime.Now; if (options.UseHandleBars) { var dropped = (DropTemplates(options.ProjectPath, options.CodeGenerationMode == CodeGenerationMode.EFCore5)); if (dropped) { project.ProjectItems.AddFromDirectory(Path.Combine(options.ProjectPath, "CodeTemplates")); } } options.UseNullableReferences = project.IsNetFramework() ? false : options.UseNullableReferences; _package.Dte2.StatusBar.Animate(true, _icon); _package.Dte2.StatusBar.Text = ReverseEngineerLocale.GeneratingCode; var revEngResult = EfRevEngLauncher.LaunchExternalRunner(options, options.CodeGenerationMode == CodeGenerationMode.EFCore5); _package.Dte2.StatusBar.Animate(false, _icon); if (options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 2) { foreach (var filePath in revEngResult.EntityTypeFilePaths) { project.ProjectItems.AddFromFile(filePath); } } if (options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 1) { foreach (var filePath in revEngResult.ContextConfigurationFilePaths) { project.ProjectItems.AddFromFile(filePath); } project.ProjectItems.AddFromFile(revEngResult.ContextFilePath); _package.Dte2.ItemOperations.OpenFile(revEngResult.ContextFilePath); } var duration = DateTime.Now - startTime; var missingProviderPackage = containsEfCoreReference.Item1 ? null : containsEfCoreReference.Item2; if (options.InstallNuGetPackage || options.SelectedToBeGenerated == 2) { missingProviderPackage = null; } _package.Dte2.StatusBar.Text = ReverseEngineerLocale.ReportingResult; var errors = reverseEngineerHelper.ReportRevEngErrors(revEngResult, missingProviderPackage); _package.Dte2.StatusBar.Text = String.Format(ReverseEngineerLocale.ReverseEngineerCompleted, duration.ToString("h\\:mm\\:ss")); EnvDteHelper.ShowMessage(errors); if (revEngResult.EntityErrors.Count > 0) { _package.LogError(revEngResult.EntityErrors, null); } if (revEngResult.EntityWarnings.Count > 0) { _package.LogError(revEngResult.EntityWarnings, null); } }
private async System.Threading.Tasks.Task SaveOptionsAsync(Project project, string optionsPath, ReverseEngineerOptions options, Tuple <List <Schema>, string> renamingOptions) { if (File.Exists(optionsPath) && File.GetAttributes(optionsPath).HasFlag(FileAttributes.ReadOnly)) { //TODO Localize VSHelper.ShowError($"Unable to save options, the file is readonly: {optionsPath}"); return; } if (!File.Exists(optionsPath + ".ignore")) { if (!Properties.Settings.Default.IncludeUiHintInConfig) { options.UiHint = null; } File.WriteAllText(optionsPath, options.Write(Path.GetDirectoryName(project.FullPath)), Encoding.UTF8); await project.AddExistingFilesAsync(new List <string> { optionsPath }.ToArray()); } if (renamingOptions.Item1 != null && !File.Exists(renamingOptions.Item2 + ".ignore") && renamingOptions.Item1.Count() > 0) { if (File.Exists(renamingOptions.Item2) && File.GetAttributes(renamingOptions.Item2).HasFlag(FileAttributes.ReadOnly)) { //TODO Localize VSHelper.ShowError($"Unable to save renaming options, the file is readonly: {renamingOptions.Item2}"); return; } File.WriteAllText(renamingOptions.Item2, CustomNameOptionsExtensions.Write(renamingOptions.Item1), Encoding.UTF8); await project.AddExistingFilesAsync(new List <string> { renamingOptions.Item2 }.ToArray()); } }
private async System.Threading.Tasks.Task GenerateFilesAsync(Project project, ReverseEngineerOptions options, Tuple <bool, string> containsEfCoreReference) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var startTime = DateTime.Now; if (options.UseHandleBars) { DropTemplates(options.OptionsPath, options.CodeGenerationMode); } options.UseNullableReferences = !await project.IsLegacyAsync() && options.UseNullableReferences; await VS.StatusBar.ShowProgressAsync(ReverseEngineerLocale.GeneratingCode, 1, 3); var revEngResult = await EfRevEngLauncher.LaunchExternalRunnerAsync(options, options.CodeGenerationMode, project); await VS.StatusBar.ShowProgressAsync(ReverseEngineerLocale.GeneratingCode, 2, 3); var tfm = await project.GetAttributeAsync("TargetFrameworkMoniker"); bool isNetStandard = tfm?.Contains(".NETStandard,Version=v2.") ?? false; if ((options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 2) && !await project.IsNetCore31OrHigherAsync() && !isNetStandard) { foreach (var filePath in revEngResult.EntityTypeFilePaths) { await project.AddExistingFilesAsync(new List <string> { filePath }.ToArray()); } } if (options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 1) { if (!await project.IsNetCore31OrHigherAsync() && !isNetStandard) { foreach (var filePath in revEngResult.ContextConfigurationFilePaths) { await project.AddExistingFilesAsync(new List <string> { filePath }.ToArray()); } await project.AddExistingFilesAsync(new List <string> { revEngResult.ContextFilePath }.ToArray()); } if (AdvancedOptions.Instance.OpenGeneratedDbContext) { var readmeName = "PowerToolsReadMe.txt"; var finalText = reverseEngineerHelper.GetReadMeText(options, File.ReadAllText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), readmeName), Encoding.UTF8)); var readmePath = Path.Combine(Path.GetTempPath(), readmeName); File.WriteAllText(readmePath, finalText, Encoding.UTF8); await VS.Documents.OpenAsync(readmePath); await VS.Documents.OpenAsync(revEngResult.ContextFilePath); } } await VS.StatusBar.ShowProgressAsync(ReverseEngineerLocale.GeneratingCode, 3, 3); var duration = DateTime.Now - startTime; var missingProviderPackage = containsEfCoreReference.Item1 ? null : containsEfCoreReference.Item2; if (options.InstallNuGetPackage || options.SelectedToBeGenerated == 2) { missingProviderPackage = null; } var errors = reverseEngineerHelper.ReportRevEngErrors(revEngResult, missingProviderPackage); await VS.StatusBar.ShowMessageAsync(string.Format(ReverseEngineerLocale.ReverseEngineerCompleted, duration.ToString("h\\:mm\\:ss"))); if (errors != ReverseEngineerLocale.ModelGeneratedSuccesfully + Environment.NewLine) { VSHelper.ShowMessage(errors); } if (revEngResult.EntityErrors.Count > 0) { package.LogError(revEngResult.EntityErrors, null); } if (revEngResult.EntityWarnings.Count > 0) { package.LogError(revEngResult.EntityWarnings, null); } Telemetry.TrackFrameworkUse(nameof(ReverseEngineerHandler), options.CodeGenerationMode); }
private async System.Threading.Tasks.Task GenerateFilesAsync(Project project, ReverseEngineerOptions options, Tuple <bool, string> containsEfCoreReference) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var startTime = DateTime.Now; if (options.UseHandleBars) { DropTemplates(options.OptionsPath, options.CodeGenerationMode); } options.UseNullableReferences = await project.IsNetFrameworkAsync() ? false : options.UseNullableReferences; //TODO Disable for now - see #1164 await SetNullableAsync(options, project); await VS.StatusBar.StartAnimationAsync(StatusAnimation.Build); await VS.StatusBar.ShowMessageAsync(ReverseEngineerLocale.GeneratingCode); var revEngResult = await EfRevEngLauncher.LaunchExternalRunnerAsync(options, options.CodeGenerationMode); await VS.StatusBar.EndAnimationAsync(StatusAnimation.Build); var tfm = await project.GetAttributeAsync("TargetFrameworkMoniker"); bool isNetStandard = tfm?.Contains(".NETStandard,Version=v2.") ?? false; if (options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 2) { if (!await project.IsNetCore31OrHigherAsync() && !isNetStandard) { foreach (var filePath in revEngResult.EntityTypeFilePaths) { await project.AddExistingFilesAsync(new List <string> { filePath }.ToArray()); } } } if (options.SelectedToBeGenerated == 0 || options.SelectedToBeGenerated == 1) { if (!await project.IsNetCore31OrHigherAsync() && !isNetStandard) { foreach (var filePath in revEngResult.ContextConfigurationFilePaths) { await project.AddExistingFilesAsync(new List <string> { filePath }.ToArray()); } await project.AddExistingFilesAsync(new List <string> { revEngResult.ContextFilePath }.ToArray()); } if (Properties.Settings.Default.OpenGeneratedDbContext) { await VS.Documents.OpenAsync(revEngResult.ContextFilePath); } } var duration = DateTime.Now - startTime; var missingProviderPackage = containsEfCoreReference.Item1 ? null : containsEfCoreReference.Item2; if (options.InstallNuGetPackage || options.SelectedToBeGenerated == 2) { missingProviderPackage = null; } await VS.StatusBar.ShowMessageAsync(ReverseEngineerLocale.ReportingResult); var errors = reverseEngineerHelper.ReportRevEngErrors(revEngResult, missingProviderPackage); await VS.StatusBar.ShowMessageAsync(string.Format(ReverseEngineerLocale.ReverseEngineerCompleted, duration.ToString("h\\:mm\\:ss"))); if (errors != ReverseEngineerLocale.ModelGeneratedSuccesfully + Environment.NewLine) { VSHelper.ShowMessage(errors); } if (revEngResult.EntityErrors.Count > 0) { _package.LogError(revEngResult.EntityErrors, null); } if (revEngResult.EntityWarnings.Count > 0) { _package.LogError(revEngResult.EntityWarnings, null); } }
public async System.Threading.Tasks.Task ReverseEngineerCodeFirstAsync(Project project) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); try { var dteH = new EnvDteHelper(); string dacpacSchema = null; if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug) { EnvDteHelper.ShowError("Cannot generate code while debugging"); return; } var projectPath = project.Properties.Item("FullPath")?.Value.ToString(); var optionsPaths = project.GetConfigFiles(); var optionsPath = optionsPaths.First(); var renamingPath = project.GetRenamingPath(); if (optionsPaths.Count > 1) { var pcd = _package.GetView <IPickConfigDialog>(); pcd.PublishConfigurations(optionsPaths.Select(m => new ConfigModel { ConfigPath = m, ProjectPath = projectPath })); var pickConfigResult = pcd.ShowAndAwaitUserResponse(true); if (!pickConfigResult.ClosedByOK) { return; } optionsPath = pickConfigResult.Payload.ConfigPath; } var databaseList = VsDataHelper.GetDataConnections(_package); var dacpacList = _package.Dte2.DTE.GetDacpacFilesInActiveSolution(EnvDteHelper.GetProjectFilesInSolution(_package)); var options = ReverseEngineerOptionsExtensions.TryRead(optionsPath); var psd = _package.GetView <IPickServerDatabaseDialog>(); if (databaseList != null && databaseList.Any()) { psd.PublishConnections(databaseList.Select(m => new DatabaseConnectionModel { ConnectionName = m.Value.Caption, ConnectionString = m.Value.ConnectionString, DatabaseType = m.Value.DatabaseType, DataConnection = m.Value.DataConnection, })); } if (dacpacList != null && dacpacList.Any()) { psd.PublishDefinitions(dacpacList.Select(m => new DatabaseDefinitionModel { FilePath = m })); } if (options != null) { if (options.FilterSchemas && options.Schemas != null && options.Schemas.Any()) { psd.PublishSchemas(options.Schemas); } psd.PublishCodeGenerationMode(options.CodeGenerationMode); if (!string.IsNullOrEmpty(options.UiHint)) { psd.PublishUiHint(options.UiHint); } } var pickDataSourceResult = psd.ShowAndAwaitUserResponse(true); if (!pickDataSourceResult.ClosedByOK) { return; } var useEFCore5 = pickDataSourceResult.Payload.IncludeViews; var filterSchemas = pickDataSourceResult.Payload.FilterSchemas; var schemas = filterSchemas ? pickDataSourceResult.Payload.Schemas : null; _package.Dte2.StatusBar.Text = "Getting ready to connect..."; DatabaseInfo dbInfo = null; if (pickDataSourceResult.Payload.Connection != null) { dbInfo = new DatabaseInfo { ConnectionString = pickDataSourceResult.Payload.Connection.ConnectionString, Caption = pickDataSourceResult.Payload.Connection.ConnectionName, DatabaseType = pickDataSourceResult.Payload.Connection.DatabaseType, DataConnection = pickDataSourceResult.Payload.Connection.DataConnection, }; } var dacpacPath = pickDataSourceResult.Payload.Definition?.FilePath; if (dbInfo == null) { dbInfo = new DatabaseInfo(); } if (!string.IsNullOrEmpty(dacpacPath)) { dbInfo.DatabaseType = DatabaseType.SQLServerDacpac; dbInfo.ConnectionString = $"Data Source=(local);Initial Catalog={Path.GetFileNameWithoutExtension(dacpacPath)};Integrated Security=true;"; dacpacPath = _package.Dte2.DTE.BuildSqlProj(dacpacPath); if (string.IsNullOrEmpty(dacpacPath)) { EnvDteHelper.ShowMessage("Unable to build selected Database Project"); return; } } if (dbInfo.DatabaseType == DatabaseType.SQLCE35 || dbInfo.DatabaseType == DatabaseType.SQLCE40 || dbInfo.DatabaseType == DatabaseType.Undefined) { EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}"); return; } _package.Dte2.StatusBar.Text = "Loading database objects..."; object icon = (short)Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Build; _package.Dte2.StatusBar.Animate(true, icon); var predefinedTables = !string.IsNullOrEmpty(dacpacPath) ? await GetDacpacTablesAsync(dacpacPath, useEFCore5) : await GetTablesAsync(dbInfo, useEFCore5, schemas); _package.Dte2.StatusBar.Animate(false, icon); var preselectedTables = new List <SerializationTableModel>(); if (options != null) { dacpacSchema = options.DefaultDacpacSchema; if (options.Tables.Count > 0) { var normalizedTables = reverseEngineerHelper.NormalizeTables(options.Tables, dbInfo.DatabaseType == DatabaseType.SQLServer); preselectedTables.AddRange(normalizedTables); } } var namingOptionsAndPath = CustomNameOptionsExtensions.TryRead(renamingPath, optionsPath); _package.Dte2.StatusBar.Clear(); var ptd = _package.GetView <IPickTablesDialog>() .AddTables(predefinedTables, namingOptionsAndPath.Item1) .PreselectTables(preselectedTables); var pickTablesResult = ptd.ShowAndAwaitUserResponse(true); if (!pickTablesResult.ClosedByOK) { return; } _package.Dte2.StatusBar.Text = "Loading options..."; var classBasis = VsDataHelper.GetDatabaseName(dbInfo.ConnectionString, dbInfo.DatabaseType); var model = reverseEngineerHelper.GenerateClassName(classBasis) + "Context"; var packageResult = project.ContainsEfCoreReference(dbInfo.DatabaseType); var presets = new ModelingOptionsModel { InstallNuGetPackage = !packageResult.Item1, ModelName = options != null ? options.ContextClassName : model, ProjectName = project.Name, Namespace = options != null ? options.ProjectRootNamespace : project.Properties.Item("DefaultNamespace").Value.ToString(), DacpacPath = dacpacPath, }; if (options != null) { presets.UseDataAnnotations = !options.UseFluentApiOnly; presets.UseDatabaseNames = options.UseDatabaseNames; presets.UsePluralizer = options.UseInflector; presets.UseDbContextSplitting = options.UseDbContextSplitting; presets.UseHandlebars = options.UseHandleBars; presets.SelectedHandlebarsLanguage = options.SelectedHandlebarsLanguage; presets.IncludeConnectionString = options.IncludeConnectionString; presets.ModelName = options.ContextClassName; presets.Namespace = options.ProjectRootNamespace; presets.OutputPath = options.OutputPath; presets.OutputContextPath = options.OutputContextPath; presets.ModelNamespace = options.ModelNamespace; presets.ContextNamespace = options.ContextNamespace; presets.SelectedToBeGenerated = options.SelectedToBeGenerated; presets.DacpacPath = options.Dacpac; presets.UseEf6Pluralizer = options.UseLegacyPluralizer; presets.MapSpatialTypes = options.UseSpatial; presets.MapNodaTimeTypes = options.UseNodaTime; presets.UseBoolPropertiesWithoutDefaultSql = options.UseBoolPropertiesWithoutDefaultSql; presets.UseNoConstructor = options.UseNoConstructor; presets.UseNoNavigations = options.UseNoNavigations; presets.UseNullableReferences = options.UseNullableReferences; } var modelDialog = _package.GetView <IModelingOptionsDialog>() .ApplyPresets(presets); _package.Dte2.StatusBar.Clear(); var modelingOptionsResult = modelDialog.ShowAndAwaitUserResponse(true); if (!modelingOptionsResult.ClosedByOK) { return; } options = new ReverseEngineerOptions { UseFluentApiOnly = !modelingOptionsResult.Payload.UseDataAnnotations, ConnectionString = dbInfo.ConnectionString, ContextClassName = modelingOptionsResult.Payload.ModelName, DatabaseType = dbInfo.DatabaseType, ProjectPath = projectPath, OutputPath = modelingOptionsResult.Payload.OutputPath, OutputContextPath = modelingOptionsResult.Payload.OutputContextPath, ContextNamespace = modelingOptionsResult.Payload.ContextNamespace, ModelNamespace = modelingOptionsResult.Payload.ModelNamespace, ProjectRootNamespace = modelingOptionsResult.Payload.Namespace, UseDatabaseNames = modelingOptionsResult.Payload.UseDatabaseNames, UseInflector = modelingOptionsResult.Payload.UsePluralizer, UseLegacyPluralizer = modelingOptionsResult.Payload.UseEf6Pluralizer, UseSpatial = modelingOptionsResult.Payload.MapSpatialTypes, UseNodaTime = modelingOptionsResult.Payload.MapNodaTimeTypes, UseDbContextSplitting = modelingOptionsResult.Payload.UseDbContextSplitting, UseHandleBars = modelingOptionsResult.Payload.UseHandlebars, SelectedHandlebarsLanguage = modelingOptionsResult.Payload.SelectedHandlebarsLanguage, IncludeConnectionString = modelingOptionsResult.Payload.IncludeConnectionString, SelectedToBeGenerated = modelingOptionsResult.Payload.SelectedToBeGenerated, UseBoolPropertiesWithoutDefaultSql = modelingOptionsResult.Payload.UseBoolPropertiesWithoutDefaultSql, UseNullableReferences = modelingOptionsResult.Payload.UseNullableReferences, UseNoConstructor = modelingOptionsResult.Payload.UseNoConstructor, UseNoNavigations = modelingOptionsResult.Payload.UseNoNavigations, Dacpac = dacpacPath, DefaultDacpacSchema = dacpacSchema, Tables = pickTablesResult.Payload.Objects.ToList(), CustomReplacers = pickTablesResult.Payload.CustomReplacers.ToList(), FilterSchemas = filterSchemas, Schemas = schemas?.ToList(), CodeGenerationMode = pickDataSourceResult.Payload.IncludeViews ? CodeGenerationMode.EFCore5 : CodeGenerationMode.EFCore3, UiHint = pickDataSourceResult.Payload.UiHint, }; if (options.DatabaseType == DatabaseType.SQLServer && string.IsNullOrEmpty(options.Dacpac)) { var rightsAndVersion = reverseEngineerHelper.HasSqlServerViewDefinitionRightsAndVersion(options.ConnectionString); if (rightsAndVersion.Item1 == false) { EnvDteHelper.ShowMessage("The SQL Server user does not have 'VIEW DEFINITION' rights, default constraints may not be available."); } if (rightsAndVersion.Item2.Major < 11) { EnvDteHelper.ShowMessage($"SQL Server version {rightsAndVersion.Item2} may not be supported."); } } if (modelingOptionsResult.Payload.UseHandlebars) { var dropped = (DropTemplates(projectPath, useEFCore5)); if (dropped) { project.ProjectItems.AddFromDirectory(Path.Combine(projectPath, "CodeTemplates")); } } var startTime = DateTime.Now; _package.Dte2.StatusBar.Animate(true, icon); _package.Dte2.StatusBar.Text = "Generating code..."; var revEngResult = EfRevEngLauncher.LaunchExternalRunner(options, useEFCore5); _package.Dte2.StatusBar.Animate(false, icon); if (modelingOptionsResult.Payload.SelectedToBeGenerated == 0 || modelingOptionsResult.Payload.SelectedToBeGenerated == 2) { foreach (var filePath in revEngResult.EntityTypeFilePaths) { project.ProjectItems.AddFromFile(filePath); } if (modelingOptionsResult.Payload.SelectedToBeGenerated == 2) { if (File.Exists(revEngResult.ContextFilePath)) { File.Delete(revEngResult.ContextFilePath); } foreach (var filePath in revEngResult.ContextConfigurationFilePaths) { if (File.Exists(filePath)) { File.Delete(filePath); } } } } if (modelingOptionsResult.Payload.SelectedToBeGenerated == 0 || modelingOptionsResult.Payload.SelectedToBeGenerated == 1) { foreach (var filePath in revEngResult.ContextConfigurationFilePaths) { project.ProjectItems.AddFromFile(filePath); } project.ProjectItems.AddFromFile(revEngResult.ContextFilePath); _package.Dte2.ItemOperations.OpenFile(revEngResult.ContextFilePath); if (modelingOptionsResult.Payload.SelectedToBeGenerated == 1) { foreach (var filePath in revEngResult.EntityTypeFilePaths) { if (File.Exists(filePath)) { File.Delete(filePath); } } } } var duration = DateTime.Now - startTime; var missingProviderPackage = packageResult.Item1 ? null : packageResult.Item2; if (modelingOptionsResult.Payload.InstallNuGetPackage || modelingOptionsResult.Payload.SelectedToBeGenerated == 2) { missingProviderPackage = null; } _package.Dte2.StatusBar.Text = "Reporting result..."; var errors = reverseEngineerHelper.ReportRevEngErrors(revEngResult, missingProviderPackage); SaveOptions(project, optionsPath, options, new Tuple <List <Schema>, string>(pickTablesResult.Payload.CustomReplacers.ToList(), namingOptionsAndPath.Item2)); if (modelingOptionsResult.Payload.InstallNuGetPackage) { _package.Dte2.StatusBar.Text = "Installing EF Core provider package"; var nuGetHelper = new NuGetHelper(); await nuGetHelper.InstallPackageAsync(packageResult.Item2, project); } _package.Dte2.StatusBar.Text = $"Reverse engineer completed in {duration:h\\:mm\\:ss}"; EnvDteHelper.ShowMessage(errors); if (revEngResult.EntityErrors.Count > 0) { _package.LogError(revEngResult.EntityErrors, null); } if (revEngResult.EntityWarnings.Count > 0) { _package.LogError(revEngResult.EntityWarnings, null); } Telemetry.TrackEvent("PowerTools.ReverseEngineer"); } catch (AggregateException ae) { foreach (var innerException in ae.Flatten().InnerExceptions) { _package.LogError(new List <string>(), innerException); } } catch (Exception exception) { _package.LogError(new List <string>(), exception); } }