private void AddButton_OnClick(object sender, RoutedEventArgs e)
        {
            try
            {
                var info = EnvDteHelper.PromptForInfo(_package);
                if (info.DatabaseType == DatabaseType.SQLCE35)
                {
                    return;
                }

                var databaseList = EnvDteHelper.GetDataConnections(_package);
                comboBox1.DisplayMemberPath = "Value.Caption";
                comboBox1.ItemsSource       = databaseList;

                int i = 0;
                foreach (var item in databaseList)
                {
                    if (item.Key == info.ConnectionString)
                    {
                        comboBox1.SelectedIndex = i;
                    }
                    i++;
                }
            }

            catch (Exception exception)
            {
                EnvDteHelper.ShowMessage(exception.ToString());
            }
        }
        public void GenerateServerDgmlFiles()
        {
            try
            {
                if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug)
                {
                    EnvDteHelper.ShowError("Cannot generate code while debugging");
                    return;
                }

                var databaseList = EnvDteHelper.GetDataConnections(_package);

                var psd     = new PickServerDatabaseDialog(databaseList, _package);
                var diagRes = psd.ShowModal();
                if (!diagRes.HasValue || !diagRes.Value)
                {
                    return;
                }

                _package.Dte2.StatusBar.Text = "Loading schema information...";

                var dbInfo = psd.SelectedDatabase.Value;

                if (dbInfo.DatabaseType == DatabaseType.SQLCE35)
                {
                    EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}");
                    return;
                }

                var ptd = new PickTablesDialog();
                using (var repository = RepositoryHelper.CreateRepository(dbInfo))
                {
                    ptd.Tables = repository.GetAllTableNamesForExclusion();
                }

                var res = ptd.ShowModal();
                if (!res.HasValue || !res.Value)
                {
                    return;
                }

                var path = Path.GetTempFileName() + ".dgml";

                using (var repository = RepositoryHelper.CreateRepository(dbInfo))
                {
                    var generator = RepositoryHelper.CreateGenerator(repository, path, dbInfo.DatabaseType);
                    generator.GenerateSchemaGraph(dbInfo.ConnectionString, ptd.Tables);
                    _package.Dte2.ItemOperations.OpenFile(path);
                    _package.Dte2.ActiveDocument.Activate();
                }
                Telemetry.TrackEvent("PowerTools.GenerateSchemaDgml");
            }
            catch (Exception ex)
            {
                _package.LogError(new List <string>(), ex);
            }
        }
示例#3
0
        public async void ReverseEngineerCodeFirst(Project project)
        {
            try
            {
                var    dteH         = new EnvDteHelper();
                var    revEng       = new EfCoreReverseEngineer();
                string dacpacSchema = null;

                if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug)
                {
                    EnvDteHelper.ShowError("Cannot generate code while debugging");
                    return;
                }

                var startTime    = DateTime.Now;
                var projectPath  = project.Properties.Item("FullPath").Value.ToString();
                var optionsPath  = Path.Combine(projectPath, "efpt.config.json");
                var renamingPath = Path.Combine(projectPath, "efpt.renaming.json");

                var databaseList = EnvDteHelper.GetDataConnections(_package);
                var dacpacList   = _package.Dte2.DTE.GetDacpacFilesInActiveSolution();

                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
                    }));
                }

                if (dacpacList != null && dacpacList.Any())
                {
                    psd.PublishDefinitions(dacpacList.Select(m => new DatabaseDefinitionModel
                    {
                        FilePath = m
                    }));
                }

                var pickDataSourceResult = psd.ShowAndAwaitUserResponse(true);
                if (!pickDataSourceResult.ClosedByOK)
                {
                    return;
                }

                _package.Dte2.StatusBar.Text = "Loading schema information...";

                // Reload the database list, in case the user has added a new database in the dialog
                databaseList = EnvDteHelper.GetDataConnections(_package);

                DatabaseInfo dbInfo = null;
                if (pickDataSourceResult.Payload.Connection != null)
                {
                    dbInfo = databaseList.Single(m => m.Value.ConnectionString == pickDataSourceResult.Payload.Connection?.ConnectionString).Value;
                }
                var dacpacPath = pickDataSourceResult.Payload.Definition?.FilePath;

                if (dbInfo == null)
                {
                    dbInfo = new DatabaseInfo();
                }

                if (!string.IsNullOrEmpty(dacpacPath))
                {
                    dbInfo.DatabaseType     = DatabaseType.SQLServer;
                    dbInfo.ConnectionString = "Data Source=.;Initial Catalog=" + Path.GetFileNameWithoutExtension(dacpacPath);
                    dacpacPath = _package.Dte2.DTE.BuildSqlProj(dacpacPath);
                    if (string.IsNullOrEmpty(dacpacPath))
                    {
                        EnvDteHelper.ShowMessage("Unable to build selected Database Project");
                        return;
                    }
                }

                if (dbInfo.DatabaseType == DatabaseType.SQLCE35)
                {
                    EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}");
                    return;
                }

                var options = ReverseEngineerOptionsExtensions.TryRead(optionsPath);

                var predefinedTables = !string.IsNullOrEmpty(dacpacPath)
                                           ? revEng.GetDacpacTables(dacpacPath)
                                           : GetTablesFromRepository(dbInfo);

                var preselectedTables = new List <TableInformationModel>();
                if (options != null)
                {
                    dacpacSchema = options.DefaultDacpacSchema;
                    if (options.Tables.Count > 0)
                    {
                        preselectedTables.AddRange(options.Tables);
                    }
                }

                var ptd = _package.GetView <IPickTablesDialog>()
                          .AddTables(predefinedTables)
                          .PreselectTables(preselectedTables);

                var customNameOptions = CustomNameOptionsExtensions.TryRead(renamingPath);

                var pickTablesResult = ptd.ShowAndAwaitUserResponse(true);
                if (!pickTablesResult.ClosedByOK)
                {
                    return;
                }

                var classBasis = string.Empty;
                if (dbInfo.DatabaseType == DatabaseType.Npgsql)
                {
                    classBasis = EnvDteHelper.GetNpgsqlDatabaseName(dbInfo.ConnectionString);
                }
                else if (dbInfo.DatabaseType == DatabaseType.Mysql)
                {
                    classBasis = EnvDteHelper.GetMysqlDatabaseName(dbInfo.ConnectionString);
                }
                else
                {
                    classBasis = RepositoryHelper.GetClassBasis(dbInfo.ConnectionString, dbInfo.DatabaseType);
                }
                var model         = revEng.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.UseHandelbars              = options.UseHandleBars;
                    presets.SelectedHandlebarsLanguage = options.SelectedHandlebarsLanguage;
                    presets.ReplaceId               = options.IdReplace;
                    presets.DoNotCombineNamespace   = options.DoNotCombineNamespace;
                    presets.IncludeConnectionString = options.IncludeConnectionString;
                    presets.ModelName               = options.ContextClassName;
                    presets.Namespace               = options.ProjectRootNamespace;
                    presets.OutputPath              = options.OutputPath;
                    presets.SelectedToBeGenerated   = options.SelectedToBeGenerated;
                }

                var modelDialog = _package.GetView <IModelingOptionsDialog>()
                                  .ApplyPresets(presets);

                _package.Dte2.StatusBar.Text = "Getting options...";

                var modelingOptionsResult = modelDialog.ShowAndAwaitUserResponse(true);
                if (!modelingOptionsResult.ClosedByOK)
                {
                    return;
                }

                options = new ReverseEngineerOptions
                {
                    UseFluentApiOnly           = !modelingOptionsResult.Payload.UseDataAnnotations,
                    ConnectionString           = dbInfo.ConnectionString,
                    ContextClassName           = modelingOptionsResult.Payload.ModelName,
                    DatabaseType               = (ReverseEngineer20.DatabaseType)dbInfo.DatabaseType,
                    ProjectPath                = projectPath,
                    OutputPath                 = modelingOptionsResult.Payload.OutputPath,
                    ProjectRootNamespace       = modelingOptionsResult.Payload.Namespace,
                    UseDatabaseNames           = modelingOptionsResult.Payload.UseDatabaseNames,
                    UseInflector               = modelingOptionsResult.Payload.UsePluralizer,
                    UseLegacyPluralizer        = options?.UseLegacyPluralizer ?? false,
                    IdReplace                  = modelingOptionsResult.Payload.ReplaceId,
                    DoNotCombineNamespace      = modelingOptionsResult.Payload.DoNotCombineNamespace,
                    UseHandleBars              = modelingOptionsResult.Payload.UseHandelbars,
                    SelectedHandlebarsLanguage = modelingOptionsResult.Payload.SelectedHandlebarsLanguage,
                    IncludeConnectionString    = modelingOptionsResult.Payload.IncludeConnectionString,
                    SelectedToBeGenerated      = modelingOptionsResult.Payload.SelectedToBeGenerated,
                    Dacpac = dacpacPath,
                    DefaultDacpacSchema = dacpacSchema,
                    Tables          = pickTablesResult.Payload.ToList(),
                    CustomReplacers = customNameOptions
                };

                _package.Dte2.StatusBar.Text = "Generating code...";

                var  tfm           = project.Properties.Item("TargetFrameworkMoniker").Value.ToString();
                bool isNetStandard = tfm.Contains(".NETStandard,Version=v2.0");

                if (modelingOptionsResult.Payload.UseHandelbars)
                {
                    var dropped = (DropTemplates(projectPath));
                    if (dropped && !project.IsNetCore() && !isNetStandard)
                    {
                        project.ProjectItems.AddFromDirectory(Path.Combine(projectPath, "CodeTemplates"));
                    }
                }

                var revEngResult = revEng.GenerateFiles(options);

                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);
                        }
                    }
                }
                if (modelingOptionsResult.Payload.SelectedToBeGenerated == 0 || modelingOptionsResult.Payload.SelectedToBeGenerated == 1)
                {
                    project.ProjectItems.AddFromFile(revEngResult.ContextFilePath);
                    if (!project.IsNetCore() && !isNetStandard)
                    {
                        _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 missingProviderPackage = packageResult.Item1 ? null : packageResult.Item2;
                if (modelingOptionsResult.Payload.InstallNuGetPackage || modelingOptionsResult.Payload.SelectedToBeGenerated == 2)
                {
                    missingProviderPackage = null;
                }

                _package.Dte2.StatusBar.Text = "Reporting result...";
                var errors = ReportRevEngErrors(revEngResult, missingProviderPackage);

                SaveOptions(project, optionsPath, options);

                if (modelingOptionsResult.Payload.InstallNuGetPackage)
                {
                    _package.Dte2.StatusBar.Text = "Installing EF Core provider package";
                    var nuGetHelper = new NuGetHelper();
                    await nuGetHelper.InstallPackageAsync(packageResult.Item2, project);
                }
                var duration = DateTime.Now - startTime;
                _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);
            }
        }
示例#4
0
        public async void ReverseEngineerCodeFirst(Project project)
        {
            try
            {
                var    dteH         = new EnvDteHelper();
                var    revEng       = new EfCoreReverseEngineer();
                string dacpacSchema = null;

                if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug)
                {
                    EnvDteHelper.ShowError("Cannot generate code while debugging");
                    return;
                }

                var startTime   = DateTime.Now;
                var projectPath = project.Properties.Item("FullPath").Value.ToString();
                var optionsPath = Path.Combine(projectPath, "efpt.config.json");

                var databaseList = EnvDteHelper.GetDataConnections(_package);
                var dacpacList   = _package.Dte2.DTE.GetDacpacFilesInActiveSolution();

                var psd = new PickServerDatabaseDialog(databaseList, _package, dacpacList);
                if (psd.ShowModal() != true)
                {
                    return;
                }

                _package.Dte2.StatusBar.Text = "Loading schema information...";

                var dbInfo     = psd.SelectedDatabase.Value;
                var dacpacPath = psd.DacpacPath;

                if (dbInfo == null)
                {
                    dbInfo = new DatabaseInfo();
                }

                if (!string.IsNullOrEmpty(dacpacPath))
                {
                    dbInfo.DatabaseType     = DatabaseType.SQLServer;
                    dbInfo.ConnectionString = "Data Source=.;Initial Catalog=" + Path.GetFileNameWithoutExtension(dacpacPath);
                    dacpacPath = _package.Dte2.DTE.BuildSqlProj(dacpacPath);
                    if (string.IsNullOrEmpty(dacpacPath))
                    {
                        EnvDteHelper.ShowMessage("Unable to build selected Database Project");
                        return;
                    }
                }

                if (dbInfo.DatabaseType == DatabaseType.SQLCE35)
                {
                    EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}");
                    return;
                }

                var ptd = new PickTablesDialog {
                    IncludeTables = true
                };
                if (!string.IsNullOrEmpty(dacpacPath))
                {
                    ptd.Tables = revEng.GetDacpacTableNames(dacpacPath);
                }
                else
                {
                    ptd.Tables = GetTablesFromRepository(dbInfo);
                }
                var options = ReverseEngineerOptionsExtensions.TryRead(optionsPath);
                if (options != null)
                {
                    dacpacSchema = options.DefaultDacpacSchema;
                    if (options.Tables.Count > 0)
                    {
                        ptd.SelectedTables = options.Tables;
                    }
                }

                if (ptd.ShowModal() != true)
                {
                    return;
                }

                var classBasis = string.Empty;
                if (dbInfo.DatabaseType == DatabaseType.Npgsql)
                {
                    classBasis = EnvDteHelper.GetNpgsqlDatabaseName(dbInfo.ConnectionString);
                }
                else
                {
                    classBasis = RepositoryHelper.GetClassBasis(dbInfo.ConnectionString, dbInfo.DatabaseType);
                }
                var model         = revEng.GenerateClassName(classBasis) + "Context";
                var packageResult = project.ContainsEfCoreReference(dbInfo.DatabaseType);

                var modelDialog = new EfCoreModelDialog(options)
                {
                    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
                };

                _package.Dte2.StatusBar.Text = "Getting options...";
                if (modelDialog.ShowModal() != true)
                {
                    return;
                }

                options = new ReverseEngineerOptions
                {
                    UseFluentApiOnly        = !modelDialog.UseDataAnnotations,
                    ConnectionString        = dbInfo.ConnectionString,
                    ContextClassName        = modelDialog.ModelName,
                    DatabaseType            = (ReverseEngineer20.DatabaseType)dbInfo.DatabaseType,
                    ProjectPath             = projectPath,
                    OutputPath              = modelDialog.OutputPath,
                    ProjectRootNamespace    = modelDialog.NameSpace,
                    UseDatabaseNames        = modelDialog.UseDatabaseNames,
                    UseInflector            = modelDialog.UsePluralizer,
                    IdReplace               = modelDialog.ReplaceId,
                    UseHandleBars           = modelDialog.UseHandelbars,
                    IncludeConnectionString = modelDialog.IncludeConnectionString,
                    SelectedToBeGenerated   = modelDialog.SelectedTobeGenerated,
                    Dacpac = dacpacPath,
                    DefaultDacpacSchema = dacpacSchema,
                    Tables = ptd.Tables
                };

                _package.Dte2.StatusBar.Text = "Generating code...";

                var  tfm           = project.Properties.Item("TargetFrameworkMoniker").Value.ToString();
                bool isNetCore     = tfm.Contains(".NETCoreApp,Version=v2.0");
                bool isNetStandard = tfm.Contains(".NETStandard,Version=v2.0");

                //TODO await update
                //if (modelDialog.UseHandelbars)
                //{
                //    var dropped = (DropTemplates(projectPath));
                //    if (dropped && !isNetCore && !isNetStandard)
                //    {
                //        project.ProjectItems.AddFromDirectory(Path.Combine(projectPath, "CodeTemplates"));
                //    }
                //}

                var revEngResult = revEng.GenerateFiles(options);

                if (modelDialog.SelectedTobeGenerated == 0 || modelDialog.SelectedTobeGenerated == 2)
                {
                    foreach (var filePath in revEngResult.EntityTypeFilePaths)
                    {
                        project.ProjectItems.AddFromFile(filePath);
                    }
                    if (modelDialog.SelectedTobeGenerated == 2)
                    {
                        if (File.Exists(revEngResult.ContextFilePath))
                        {
                            File.Delete(revEngResult.ContextFilePath);
                        }
                    }
                }
                if (modelDialog.SelectedTobeGenerated == 0 || modelDialog.SelectedTobeGenerated == 1)
                {
                    project.ProjectItems.AddFromFile(revEngResult.ContextFilePath);
                    if (!isNetCore && !isNetStandard)
                    {
                        _package.Dte2.ItemOperations.OpenFile(revEngResult.ContextFilePath);
                    }
                    if (modelDialog.SelectedTobeGenerated == 1)
                    {
                        foreach (var filePath in revEngResult.EntityTypeFilePaths)
                        {
                            if (File.Exists(filePath))
                            {
                                File.Delete(filePath);
                            }
                        }
                    }
                }

                var missingProviderPackage = packageResult.Item1 ? null : packageResult.Item2;
                if (modelDialog.InstallNuGetPackage)
                {
                    missingProviderPackage = null;
                }

                _package.Dte2.StatusBar.Text = "Reporting result...";
                var errors = ReportRevEngErrors(revEngResult, missingProviderPackage);

                SaveOptions(project, optionsPath, options);

                if (modelDialog.InstallNuGetPackage)
                {
                    _package.Dte2.StatusBar.Text = "Installing EF Core provider package";
                    var nuGetHelper = new NuGetHelper();
                    await nuGetHelper.InstallPackageAsync(packageResult.Item2, project);
                }
                var duration = DateTime.Now - startTime;
                _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);
            }
        }
示例#5
0
        public void GenerateServerDgmlFiles()
        {
            try
            {
                if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug)
                {
                    EnvDteHelper.ShowError("Cannot generate code while debugging");
                    return;
                }

                var databaseList = EnvDteHelper.GetDataConnections(_package);

                var psd = _package.GetView <IPickServerDatabaseDialog>();
                psd.PublishConnections(databaseList.Select(m => new DatabaseConnectionModel
                {
                    ConnectionName   = m.Value.Caption,
                    ConnectionString = m.Value.ConnectionString,
                    DatabaseType     = m.Value.DatabaseType
                }));

                var pickDataSourceResult = psd.ShowAndAwaitUserResponse(true);
                if (!pickDataSourceResult.ClosedByOK)
                {
                    return;
                }

                _package.Dte2.StatusBar.Text = "Loading schema information...";

                // Reload the database list, in case the user has added a new database in the dialog
                databaseList = EnvDteHelper.GetDataConnections(_package);

                DatabaseInfo dbInfo = null;
                if (pickDataSourceResult.Payload.Connection != null)
                {
                    dbInfo = databaseList.Single(m => m.Value.ConnectionString == pickDataSourceResult.Payload.Connection?.ConnectionString).Value;
                }

                if (dbInfo == null)
                {
                    // User didn't select a database, should be impossible, though
                    return;
                }

                if (dbInfo.DatabaseType == DatabaseType.SQLCE35 ||
                    dbInfo.DatabaseType == DatabaseType.Mysql ||
                    dbInfo.DatabaseType == DatabaseType.Npgsql)
                {
                    EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}");
                    return;
                }

                var predefinedTables = new List <TableInformationModel>();
                using (var repository = RepositoryHelper.CreateRepository(dbInfo))
                {
                    var tables = repository.GetAllTableNamesForExclusion();
                    foreach (var table in tables)
                    {
                        predefinedTables.Add(new TableInformationModel(table, true, false));
                    }
                }

                var ptd = _package.GetView <IPickTablesDialog>()
                          .AddTables(predefinedTables);

                var(closedByOk, selectedTables) = ptd.ShowAndAwaitUserResponse(true);
                if (!closedByOk)
                {
                    return;
                }
                var unselectedTables = predefinedTables.Except(selectedTables).Select(m => m.Name).ToList();

                var name = RepositoryHelper.GetClassBasis(dbInfo.ConnectionString, dbInfo.DatabaseType);

                var path = Path.Combine(Path.GetTempPath(),
                                        name + ".schema.dgml");

                if (File.Exists(path))
                {
                    File.SetAttributes(path, FileAttributes.Normal);
                }

                using (var repository = RepositoryHelper.CreateRepository(dbInfo))
                {
                    var generator = RepositoryHelper.CreateGenerator(repository, path, dbInfo.DatabaseType);
                    generator.GenerateSchemaGraph(dbInfo.ConnectionString, unselectedTables);
                    File.SetAttributes(path, FileAttributes.ReadOnly);
                    _package.Dte2.ItemOperations.OpenFile(path);
                    _package.Dte2.ActiveDocument.Activate();
                }
                Telemetry.TrackEvent("PowerTools.GenerateSchemaDgml");
            }
            catch (Exception ex)
            {
                _package.LogError(new List <string>(), ex);
            }
        }
        public async void ReverseEngineerCodeFirst(Project project)
        {
            try
            {
                if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug)
                {
                    EnvDteHelper.ShowError("Cannot generate code while debugging");
                    return;
                }

                var startTime = DateTime.Now;

                var databaseList = EnvDteHelper.GetDataConnections(_package);

                var psd     = new PickServerDatabaseDialog(databaseList, _package);
                var diagRes = psd.ShowModal();
                if (!diagRes.HasValue || !diagRes.Value)
                {
                    return;
                }

                // Show dialog with SqlClient selected by default
                _package.Dte2.StatusBar.Text = "Loading schema information...";

                var dbInfo = psd.SelectedDatabase.Value;

                if (dbInfo.DatabaseType == DatabaseType.SQLCE35)
                {
                    EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}");
                    return;
                }

                var ptd = new PickTablesDialog {
                    IncludeTables = true
                };
                using (var repository = RepositoryHelper.CreateRepository(dbInfo))
                {
                    ptd.Tables = repository.GetAllTableNamesForExclusion();
                }

                var res = ptd.ShowModal();
                if (!res.HasValue || !res.Value)
                {
                    return;
                }

                var classBasis = RepositoryHelper.GetClassBasis(dbInfo.ConnectionString, dbInfo.DatabaseType);

                var dteH   = new EnvDteHelper();
                var revEng = new EfCoreReverseEngineer();

                var model         = revEng.GenerateClassName(classBasis) + "Context";
                var packageResult = dteH.ContainsEfCoreReference(project, dbInfo.DatabaseType);

                var modelDialog = new EfCoreModelDialog
                {
                    InstallNuGetPackage = !packageResult.Item1,
                    ModelName           = model,
                    ProjectName         = project.Name,
                    NameSpace           = project.Properties.Item("DefaultNamespace").Value.ToString()
                };

                _package.Dte2.StatusBar.Text = "Getting options...";
                var result = modelDialog.ShowModal();
                if (!result.HasValue || result.Value != true)
                {
                    return;
                }

                var projectPath = project.Properties.Item("FullPath").Value.ToString();

                var options = new ReverseEngineerOptions
                {
                    UseFluentApiOnly     = !modelDialog.UseDataAnnotations,
                    ConnectionString     = dbInfo.ConnectionString,
                    ContextClassName     = modelDialog.ModelName,
                    DatabaseType         = (ReverseEngineer20.DatabaseType)dbInfo.DatabaseType,
                    ProjectPath          = projectPath,
                    OutputPath           = modelDialog.OutputPath,
                    ProjectRootNamespace = modelDialog.NameSpace,
                    UseDatabaseNames     = modelDialog.UseDatabaseNames,
                    UseInflector         = modelDialog.UsePluralizer,
                    IdReplace            = modelDialog.ReplaceId,
                    UseHandleBars        = modelDialog.UseHandelbars,
                    Tables = ptd.Tables
                };

                _package.Dte2.StatusBar.Text = "Generating code...";

                if (modelDialog.UseHandelbars)
                {
                    if (DropTemplates(projectPath))
                    {
                        project.ProjectItems.AddFromDirectory(Path.Combine(projectPath, "CodeTemplates"));
                    }
                }

                var revEngResult = revEng.GenerateFiles(options);

                if (modelDialog.SelectedTobeGenerated == 0 || modelDialog.SelectedTobeGenerated == 2)
                {
                    foreach (var filePath in revEngResult.EntityTypeFilePaths)
                    {
                        project.ProjectItems.AddFromFile(filePath);
                    }
                }
                if (modelDialog.SelectedTobeGenerated == 0 || modelDialog.SelectedTobeGenerated == 1)
                {
                    project.ProjectItems.AddFromFile(revEngResult.ContextFilePath);
                    _package.Dte2.ItemOperations.OpenFile(revEngResult.ContextFilePath);
                }

                packageResult = dteH.ContainsEfCoreReference(project, dbInfo.DatabaseType);

                var missingProviderPackage = packageResult.Item1 ? null : packageResult.Item2;
                if (modelDialog.InstallNuGetPackage)
                {
                    missingProviderPackage = null;
                }

                _package.Dte2.StatusBar.Text = "Reporting result...";
                var errors = ReportRevEngErrors(revEngResult, missingProviderPackage);

                if (modelDialog.InstallNuGetPackage)
                {
                    _package.Dte2.StatusBar.Text = "Installing EF Core provider package";
                    var nuGetHelper = new NuGetHelper();
                    await nuGetHelper.InstallPackageAsync(packageResult.Item2, project);
                }
                var duration = DateTime.Now - startTime;
                _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);
            }
        }
        public async System.Threading.Tasks.Task ReverseEngineerCodeFirstAsync(Project project)
        {
            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,
                    }));

                    var pickConfigResult = pcd.ShowAndAwaitUserResponse(true);
                    if (!pickConfigResult.ClosedByOK)
                    {
                        return;
                    }

                    optionsPath = pickConfigResult.Payload.ConfigPath;
                }

                var databaseList = EnvDteHelper.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
                    }));
                }

                if (dacpacList != null && dacpacList.Any())
                {
                    psd.PublishDefinitions(dacpacList.Select(m => new DatabaseDefinitionModel
                    {
                        FilePath = m
                    }));
                }

                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 = "Loading table list...";

                // Reload the database list, in case the user has added a new database in the dialog
                databaseList = EnvDteHelper.GetDataConnections(_package);

                DatabaseInfo dbInfo = null;
                if (pickDataSourceResult.Payload.Connection != null)
                {
                    dbInfo = databaseList.Single(m => m.Value.ConnectionString == pickDataSourceResult.Payload.Connection?.ConnectionString).Value;
                }
                var dacpacPath = pickDataSourceResult.Payload.Definition?.FilePath;

                if (dbInfo == null)
                {
                    dbInfo = new DatabaseInfo();
                }

                if (!string.IsNullOrEmpty(dacpacPath))
                {
                    dbInfo.DatabaseType     = DatabaseType.SQLServer;
                    dbInfo.ConnectionString = "Data Source=.;Initial Catalog=" + Path.GetFileNameWithoutExtension(dacpacPath);
                    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)
                {
                    EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}");
                    return;
                }

                //TODO Enable when released
                if (useEFCore5 && (dbInfo.DatabaseType == DatabaseType.Oracle))
                {
                    EnvDteHelper.ShowError($"Unsupported provider with EF Core 5.0: {dbInfo.DatabaseType}");
                    return;
                }

                List <TableInformationModel> predefinedTables = !string.IsNullOrEmpty(dacpacPath)
                                           ? GetDacpacTables(dacpacPath, useEFCore5)
                                           : GetTables(dbInfo, useEFCore5, schemas);

                var preselectedTables = new List <TableInformationModel>();
                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 ptd = _package.GetView <IPickTablesDialog>()
                          .AddTables(predefinedTables)
                          .PreselectTables(preselectedTables);

                var customNameOptions = CustomNameOptionsExtensions.TryRead(renamingPath);

                var pickTablesResult = ptd.ShowAndAwaitUserResponse(true);
                if (!pickTablesResult.ClosedByOK)
                {
                    return;
                }

                var classBasis    = EnvDteHelper.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;
                }

                var modelDialog = _package.GetView <IModelingOptionsDialog>()
                                  .ApplyPresets(presets);

                _package.Dte2.StatusBar.Text = "Getting options...";

                var modelingOptionsResult = modelDialog.ShowAndAwaitUserResponse(true);
                if (!modelingOptionsResult.ClosedByOK)
                {
                    return;
                }

                options = new ReverseEngineerOptions
                {
                    UseFluentApiOnly           = !modelingOptionsResult.Payload.UseDataAnnotations,
                    ConnectionString           = dbInfo.ConnectionString,
                    ContextClassName           = modelingOptionsResult.Payload.ModelName,
                    DatabaseType               = (ReverseEngineer20.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,
                    Dacpac = dacpacPath,
                    DefaultDacpacSchema = dacpacSchema,
                    Tables          = pickTablesResult.Payload.ToList(),
                    CustomReplacers = customNameOptions,
                    FilterSchemas   = filterSchemas,
                    Schemas         = schemas?.ToList()
                };

                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.");
                    }
                }

                var  tfm           = project.Properties.Item("TargetFrameworkMoniker").Value.ToString();
                bool isNetStandard = tfm.Contains(".NETStandard,Version=v2.");

                if (modelingOptionsResult.Payload.UseHandlebars)
                {
                    var dropped = (DropTemplates(projectPath, useEFCore5));
                    if (dropped && !project.IsNetCore() && !isNetStandard)
                    {
                        project.ProjectItems.AddFromDirectory(Path.Combine(projectPath, "CodeTemplates"));
                    }
                }

                var startTime = DateTime.Now;

                _package.Dte2.StatusBar.Text = "Generating code...";

                var revEngResult = EfRevEngLauncher.LaunchExternalRunner(options, useEFCore5);

                if (modelingOptionsResult.Payload.SelectedToBeGenerated == 0 || modelingOptionsResult.Payload.SelectedToBeGenerated == 2)
                {
                    foreach (var filePath in revEngResult.EntityTypeFilePaths)
                    {
                        if (!project.IsNetCore() && !isNetStandard)
                        {
                            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)
                {
                    if (!project.IsNetCore() && !isNetStandard)
                    {
                        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);

                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);
            }
        }
        public void GenerateServerDgmlFiles()
        {
            try
            {
                if (_package.Dte2.Mode == vsIDEMode.vsIDEModeDebug)
                {
                    EnvDteHelper.ShowError("Cannot generate code while debugging");
                    return;
                }

                var databaseList = EnvDteHelper.GetDataConnections(_package);

                var psd     = new PickServerDatabaseDialog(databaseList, _package, new Dictionary <string, string>());
                var diagRes = psd.ShowModal();
                if (!diagRes.HasValue || !diagRes.Value)
                {
                    return;
                }

                _package.Dte2.StatusBar.Text = "Loading schema information...";

                var dbInfo = psd.SelectedDatabase.Value;

                if (dbInfo.DatabaseType == DatabaseType.SQLCE35)
                {
                    EnvDteHelper.ShowError($"Unsupported provider: {dbInfo.ServerVersion}");
                    return;
                }

                var ptd = new PickTablesDialog();
                using (var repository = RepositoryHelper.CreateRepository(dbInfo))
                {
                    var ti     = new List <TableInformation>();
                    var tables = repository.GetAllTableNamesForExclusion();
                    foreach (var table in tables)
                    {
                        ti.Add(TableInformation.Parse(table));
                    }
                    ptd.Tables = ti;
                }

                var res = ptd.ShowModal();
                if (!res.HasValue || !res.Value)
                {
                    return;
                }

                var name = RepositoryHelper.GetClassBasis(dbInfo.ConnectionString, dbInfo.DatabaseType);

                var path = Path.Combine(Path.GetTempPath(),
                                        name + ".schema.dgml");

                if (File.Exists(path))
                {
                    File.SetAttributes(path, FileAttributes.Normal);
                }

                using (var repository = RepositoryHelper.CreateRepository(dbInfo))
                {
                    var generator = RepositoryHelper.CreateGenerator(repository, path, dbInfo.DatabaseType);
                    generator.GenerateSchemaGraph(dbInfo.ConnectionString, ptd.Tables.Select(m => m.UnsafeFullName).ToList());
                    File.SetAttributes(path, FileAttributes.ReadOnly);
                    _package.Dte2.ItemOperations.OpenFile(path);
                    _package.Dte2.ActiveDocument.Activate();
                }
                Telemetry.TrackEvent("PowerTools.GenerateSchemaDgml");
            }
            catch (Exception ex)
            {
                _package.LogError(new List <string>(), ex);
            }
        }