private void SaveProjectFile(Project project, EfTextTemplateHost efHost, TemplateProcessor templateProcessor, string entityName, string defaultNameSpaceSuffix, string templateName) { var projectRoot = new FileInfo(project.FullName).Directory.FullName; var contextContents = templateProcessor.Process($"{projectRoot}\\CodeTemplates\\ReverseEngineerCodeFirst\\" + templateName, efHost); if (string.IsNullOrWhiteSpace(efHost.NameSpaceSuffix)) { efHost.NameSpaceSuffix = defaultNameSpaceSuffix; } var modelsDirectory = GetModelSavePath(project.GetProjectDir(), efHost.NameSpaceSuffix); var modelFileName = Path.Combine(modelsDirectory, entityName + efHost.NameSuffix + efHost.FileExtension); project.AddNewFile(modelFileName, contextContents); }
public void ReverseEngineerCodeFirst(Project project) { Contract.Requires(project != null); try { // Show dialog with SqlClient selected by default var dialogFactory = _package.GetService <IVsDataConnectionDialogFactory>(); var dialog = dialogFactory.CreateConnectionDialog(); dialog.AddAllSources(); dialog.SelectedSource = new Guid("067ea0d9-ba62-43f7-9106-34930c60c528"); var dialogResult = dialog.ShowDialog(connect: true); if (dialogResult != null) { // Find connection string and provider _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_LoadSchema; var connection = (DbConnection)dialogResult.GetLockedProviderObject(); var connectionString = connection.ConnectionString; var providerManager = (IVsDataProviderManager)Package.GetGlobalService(typeof(IVsDataProviderManager)); IVsDataProvider dp; providerManager.Providers.TryGetValue(dialogResult.Provider, out dp); var providerInvariant = (string)dp.GetProperty("InvariantName"); // Load store schema var storeGenerator = new EntityStoreSchemaGenerator(providerInvariant, connectionString, "dbo"); storeGenerator.GenerateForeignKeyProperties = true; var errors = storeGenerator.GenerateStoreMetadata(_storeMetadataFilters).Where(e => e.Severity == EdmSchemaErrorSeverity.Error); errors.HandleErrors(Strings.ReverseEngineer_SchemaError); // Generate default mapping _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateMapping; var contextName = connection.Database.Replace(" ", string.Empty).Replace(".", string.Empty) + "Context"; var modelGenerator = new EntityModelSchemaGenerator(storeGenerator.EntityContainer, "DefaultNamespace", contextName); modelGenerator.PluralizationService = PluralizationService.CreateService(new CultureInfo("en")); modelGenerator.GenerateForeignKeyProperties = true; modelGenerator.GenerateMetadata(); // Pull out info about types to be generated var entityTypes = modelGenerator.EdmItemCollection.OfType <EntityType>().ToArray(); var mappings = new EdmMapping(modelGenerator, storeGenerator.StoreItemCollection); // Find the project to add the code to var vsProject = (VSLangProj.VSProject)project.Object; var projectDirectory = new FileInfo(project.FileName).Directory; var projectNamespace = (string)project.Properties.Item("RootNamespace").Value; var references = vsProject.References.Cast <VSLangProj.Reference>(); if (!references.Any(r => r.Name == "EntityFramework")) { // Add EF References _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_InstallEntityFramework; try { project.InstallPackage("EntityFramework"); } catch (Exception ex) { _package.LogError(Strings.ReverseEngineer_InstallEntityFrameworkError, ex); } } // Generate Entity Classes and Mappings _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateClasses; var templateProcessor = new TemplateProcessor(project); var modelsNamespace = projectNamespace + ".Models"; var modelsDirectory = Path.Combine(projectDirectory.FullName, "Models"); var mappingNamespace = modelsNamespace + ".Mapping"; var mappingDirectory = Path.Combine(modelsDirectory, "Mapping"); var entityFrameworkVersion = GetEntityFrameworkVersion(references); foreach (var entityType in entityTypes) { // Generate the code file var entityHost = new EfTextTemplateHost { EntityType = entityType, EntityContainer = modelGenerator.EntityContainer, Namespace = modelsNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion, TableSet = mappings.EntityMappings[entityType].Item1, PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2, ManyToManyMappings = mappings.ManyToManyMappings }; var entityContents = templateProcessor.Process(Templates.EntityTemplate, entityHost); var filePath = Path.Combine(modelsDirectory, entityType.Name + entityHost.FileExtension); project.AddNewFile(filePath, entityContents); var mappingHost = new EfTextTemplateHost { EntityType = entityType, EntityContainer = modelGenerator.EntityContainer, Namespace = mappingNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion, TableSet = mappings.EntityMappings[entityType].Item1, PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2, ManyToManyMappings = mappings.ManyToManyMappings }; var mappingContents = templateProcessor.Process(Templates.MappingTemplate, mappingHost); var mappingFilePath = Path.Combine(mappingDirectory, entityType.Name + "Map" + mappingHost.FileExtension); project.AddNewFile(mappingFilePath, mappingContents); } // Generate Context _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateContext; var contextHost = new EfTextTemplateHost { EntityContainer = modelGenerator.EntityContainer, Namespace = modelsNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion }; var contextContents = templateProcessor.Process(Templates.ContextTemplate, contextHost); var contextFilePath = Path.Combine(modelsDirectory, modelGenerator.EntityContainer.Name + contextHost.FileExtension); var contextItem = project.AddNewFile(contextFilePath, contextContents); AddConnectionStringToConfigFile(project, connectionString, providerInvariant, modelGenerator.EntityContainer.Name); if (contextItem != null) { // Open context class when done _package.DTE2.ItemOperations.OpenFile(contextFilePath); } _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_Complete; } } catch (Exception exception) { _package.LogError(Strings.ReverseEngineer_Error, exception); } }
public void ReverseEngineerCodeFirst(Project project) { DebugCheck.NotNull(project); try { Stopwatch watcher = new Stopwatch(); watcher.Start(); string connectionString = string.Empty; string providerInvariant = string.Empty; string databaseName = string.Empty; bool isNewConnectionString = false; // Show available connection string var existingConnections = GetConnectionstrings(project); Connections connectionDialog = new Connections(existingConnections.Select(x => x.Name)); connectionDialog.ShowModal(); if (connectionDialog.IsConnectionStringSelected) { var selected = connectionDialog.SelectedConnectionString; var selectedConnectionSetting = existingConnections.First(x => x.Name.Equals(selected)); providerInvariant = selectedConnectionSetting.ProviderName; connectionString = selectedConnectionSetting.ConnectionString; var dbConnection = DbProviderFactories.GetFactory(providerInvariant).CreateConnection(); dbConnection.ConnectionString = connectionString; databaseName = dbConnection.Database; } else { // Show dialog with SqlClient selected by default var dialogFactory = _package.GetService <IVsDataConnectionDialogFactory>(); var dialog = dialogFactory.CreateConnectionDialog(); dialog.AddAllSources(); dialog.SelectedSource = new Guid("067ea0d9-ba62-43f7-9106-34930c60c528"); var dialogResult = dialog.ShowDialog(connect: true); if (dialogResult != null) { // Find connection string and provider var connection = (DbConnection)dialogResult.GetLockedProviderObject(); connectionString = connection.ConnectionString; var providerManager = (IVsDataProviderManager)Package.GetGlobalService(typeof(IVsDataProviderManager)); IVsDataProvider dp; providerManager.Providers.TryGetValue(dialogResult.Provider, out dp); providerInvariant = (string)dp.GetProperty("InvariantName"); databaseName = connection.Database; isNewConnectionString = true; } else { // User selected not to proceed by clicking cancel or closes window. return; } } // Load store schema _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_LoadingSchema; var storeGenerator = new EntityStoreSchemaGenerator(providerInvariant, connectionString, "dbo"); storeGenerator.GenerateForeignKeyProperties = true; var errors = storeGenerator.GenerateStoreMetadata(_storeMetadataFilters).Where(e => e.Severity == EdmSchemaErrorSeverity.Error); errors.HandleErrors(Strings.ReverseEngineer_SchemaError); // Generate default mapping _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateMapping; var contextName = databaseName.Replace(" ", string.Empty).Replace(".", string.Empty) + "Context"; var modelGenerator = new EntityModelSchemaGenerator(storeGenerator.EntityContainer, "DefaultNamespace", contextName); modelGenerator.PluralizationService = PluralizationService.CreateService(new CultureInfo("en")); modelGenerator.GenerateForeignKeyProperties = true; modelGenerator.GenerateMetadata(); // Pull out info about types to be generated var entityTypes = modelGenerator.EdmItemCollection.OfType <EntityType>().ToArray(); var mappings = new EdmMapping(modelGenerator, storeGenerator.StoreItemCollection); // Find the project to add the code to var vsProject = (VSLangProj.VSProject)project.Object; var projectDirectory = new FileInfo(project.FileName).Directory; var defaultProjectNameSpace = (string)project.Properties.Item("RootNamespace").Value; var references = vsProject.References.Cast <VSLangProj.Reference>(); if (!references.Any(r => r.Name == "EntityFramework")) { // Add EF References _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_InstallEntityFramework; try { project.InstallPackage("EntityFramework"); } catch (Exception ex) { _package.LogError(Strings.ReverseEngineer_InstallEntityFrameworkError, ex); } } // Generate Entity Classes and Mappings var templateProcessor = new TemplateProcessor(project); var modelsNamespaceSuffixDefault = "Models"; var mappingNamespaceSuffixDefault = "Mappings"; var projectNamespace = defaultProjectNameSpace; var modelsNamespace = string.Concat(projectNamespace, ".", modelsNamespaceSuffixDefault); var mappingNamespace = string.Concat(modelsNamespace, ".", mappingNamespaceSuffixDefault); var modelsDirectory = projectDirectory.FullName; var mappingDirectory = projectDirectory.FullName; var contextDirectory = projectDirectory.FullName; var entityFrameworkVersion = GetEntityFrameworkVersion(references); ConcurrentDictionary <string, string> models = new ConcurrentDictionary <string, string>(); ConcurrentDictionary <string, string> maps = new ConcurrentDictionary <string, string>(); // Process the templates and generate content Parallel.ForEach(entityTypes, (entityType) => { _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateClasses(entityType.Name); var entityHost = new EfTextTemplateHost { EntityType = entityType, EntityContainer = modelGenerator.EntityContainer, Namespace = projectNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion, TableSet = mappings.EntityMappings[entityType].Item1, PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2, ManyToManyMappings = mappings.ManyToManyMappings }; var entityContents = templateProcessor.Process(Templates.EntityTemplate, entityHost); models.TryAdd(entityType.Name + entityHost.FileExtension, entityContents); var mappingHost = new EfTextTemplateHost { EntityType = entityType, EntityContainer = modelGenerator.EntityContainer, Namespace = projectNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion, TableSet = mappings.EntityMappings[entityType].Item1, PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2, ManyToManyMappings = mappings.ManyToManyMappings }; var mappingContents = templateProcessor.Process(Templates.MappingTemplate, mappingHost); maps.TryAdd(entityType.Name + "Map" + mappingHost.FileExtension, mappingContents); }); // Generate Context _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateContext; var contextHost = new EfTextTemplateHost { EntityContainer = modelGenerator.EntityContainer, Namespace = projectNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion }; var contextContents = templateProcessor.Process(Templates.ContextTemplate, contextHost); ProjectFilesPathGenUtility.SyncDirectoryWithNamespace( defaultProjectNameSpace, contextHost.Namespace, modelsNamespaceSuffixDefault, projectDirectory.FullName, ref contextDirectory); var contextFilePath = Path.Combine(contextDirectory, modelGenerator.EntityContainer.Name + contextHost.FileExtension); _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_AddingFiles; var contextItem = project.AddNewFile(contextFilePath, contextContents); // sync model directory ProjectFilesPathGenUtility.SyncDirectoryWithNamespace( defaultProjectNameSpace, contextHost.ModelsNamespace, modelsNamespaceSuffixDefault, projectDirectory.FullName, ref modelsDirectory); // Add models Parallel.ForEach(models, (file) => { project.AddNewFile(Path.Combine(modelsDirectory, file.Key), file.Value); }); // sync project mapping directory ProjectFilesPathGenUtility.SyncDirectoryWithNamespace( defaultProjectNameSpace, contextHost.MappingNamespace, mappingNamespaceSuffixDefault, projectDirectory.FullName, ref mappingDirectory); // Add mappings Parallel.ForEach(maps, (file) => { project.AddNewFile(Path.Combine(mappingDirectory, file.Key), file.Value); }); if (isNewConnectionString) { AddConnectionStringToConfigFile(project, connectionString, providerInvariant, modelGenerator.EntityContainer.Name); } if (contextItem != null) { // Open context class when done _package.DTE2.ItemOperations.OpenFile(contextFilePath); } watcher.Stop(); _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_Complete((int)watcher.Elapsed.TotalSeconds); } catch (Exception exception) { _package.LogError(Strings.ReverseEngineer_Error, exception); } }
public void ReverseEngineerCodeFirst(Project project) { DebugCheck.NotNull(project); try { // Show dialog with SqlClient selected by default var dialogFactory = _package.GetService<IVsDataConnectionDialogFactory>(); var dialog = dialogFactory.CreateConnectionDialog(); dialog.AddAllSources(); dialog.SelectedSource = new Guid("067ea0d9-ba62-43f7-9106-34930c60c528"); var dialogResult = dialog.ShowDialog(connect: true); if (dialogResult != null) { // Find connection string and provider _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_LoadSchema; var connection = (DbConnection)dialogResult.GetLockedProviderObject(); var connectionString = connection.ConnectionString; var providerManager = (IVsDataProviderManager)Package.GetGlobalService(typeof(IVsDataProviderManager)); IVsDataProvider dp; providerManager.Providers.TryGetValue(dialogResult.Provider, out dp); var providerInvariant = (string)dp.GetProperty("InvariantName"); // Load store schema var storeGenerator = new EntityStoreSchemaGenerator(providerInvariant, connectionString, "dbo"); storeGenerator.GenerateForeignKeyProperties = true; var errors = storeGenerator.GenerateStoreMetadata(_storeMetadataFilters).Where(e => e.Severity == EdmSchemaErrorSeverity.Error); errors.HandleErrors(Strings.ReverseEngineer_SchemaError); // Generate default mapping _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateMapping; var contextName = connection.Database.Replace(" ", string.Empty).Replace(".", string.Empty) + "Context"; var modelGenerator = new EntityModelSchemaGenerator(storeGenerator.EntityContainer, "DefaultNamespace", contextName); modelGenerator.PluralizationService = PluralizationService.CreateService(new CultureInfo("en")); modelGenerator.GenerateForeignKeyProperties = true; modelGenerator.GenerateMetadata(); // Pull out info about types to be generated var entityTypes = modelGenerator.EdmItemCollection.OfType<EntityType>().ToArray(); var mappings = new EdmMapping(modelGenerator, storeGenerator.StoreItemCollection); // Find the project to add the code to var vsProject = (VSLangProj.VSProject)project.Object; var projectDirectory = new FileInfo(project.FileName).Directory; var projectNamespace = (string)project.Properties.Item("RootNamespace").Value; var references = vsProject.References.Cast<VSLangProj.Reference>(); if (!references.Any(r => r.Name == "EntityFramework")) { // Add EF References _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_InstallEntityFramework; try { project.InstallPackage("EntityFramework"); } catch (Exception ex) { _package.LogError(Strings.ReverseEngineer_InstallEntityFrameworkError, ex); } } // Generate Entity Classes and Mappings _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateClasses; var templateProcessor = new TemplateProcessor(project); var modelsNamespace = projectNamespace + ".Models"; var modelsDirectory = Path.Combine(projectDirectory.FullName, "Models"); var mappingNamespace = modelsNamespace + ".Mapping"; var mappingDirectory = Path.Combine(modelsDirectory, "Mapping"); var entityFrameworkVersion = GetEntityFrameworkVersion(references); foreach (var entityType in entityTypes) { // Generate the code file var entityHost = new EfTextTemplateHost { EntityType = entityType, EntityContainer = modelGenerator.EntityContainer, Namespace = modelsNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion, TableSet = mappings.EntityMappings[entityType].Item1, PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2, ManyToManyMappings = mappings.ManyToManyMappings }; var entityContents = templateProcessor.Process(Templates.EntityTemplate, entityHost); var filePath = Path.Combine(modelsDirectory, entityType.Name + entityHost.FileExtension); project.AddNewFile(filePath, entityContents); var mappingHost = new EfTextTemplateHost { EntityType = entityType, EntityContainer = modelGenerator.EntityContainer, Namespace = mappingNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion, TableSet = mappings.EntityMappings[entityType].Item1, PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2, ManyToManyMappings = mappings.ManyToManyMappings }; var mappingContents = templateProcessor.Process(Templates.MappingTemplate, mappingHost); var mappingFilePath = Path.Combine(mappingDirectory, entityType.Name + "Map" + mappingHost.FileExtension); project.AddNewFile(mappingFilePath, mappingContents); } // Generate Context _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateContext; var contextHost = new EfTextTemplateHost { EntityContainer = modelGenerator.EntityContainer, Namespace = modelsNamespace, ModelsNamespace = modelsNamespace, MappingNamespace = mappingNamespace, EntityFrameworkVersion = entityFrameworkVersion }; var contextContents = templateProcessor.Process(Templates.ContextTemplate, contextHost); var contextFilePath = Path.Combine(modelsDirectory, modelGenerator.EntityContainer.Name + contextHost.FileExtension); var contextItem = project.AddNewFile(contextFilePath, contextContents); AddConnectionStringToConfigFile(project, connectionString, providerInvariant, modelGenerator.EntityContainer.Name); if (contextItem != null) { // Open context class when done _package.DTE2.ItemOperations.OpenFile(contextFilePath); } _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_Complete; } } catch (Exception exception) { _package.LogError(Strings.ReverseEngineer_Error, exception); } }