private static void AddConnectionStringToConfigFile(Project project, string connectionString, string providerInvariant, string connectionStringName)
        {
            Contract.Requires(project != null);
            Contract.Requires(!string.IsNullOrWhiteSpace(providerInvariant));
            Contract.Requires(!string.IsNullOrWhiteSpace(connectionStringName));

            // Find App.config or Web.config
            var configFilePath = Path.Combine(
                project.GetProjectDir(),
                project.IsWebProject()
                    ? "Web.config"
                    : "App.config");

            // Either load up the existing file or create a blank file
            var config = ConfigurationManager.OpenMappedExeConfiguration(
                new ExeConfigurationFileMap {
                ExeConfigFilename = configFilePath
            },
                ConfigurationUserLevel.None);

            // Find or create the connectionStrings section
            var connectionStringSettings = config.ConnectionStrings
                                           .ConnectionStrings
                                           .Cast <ConnectionStringSettings>()
                                           .FirstOrDefault(css => css.Name == connectionStringName);

            if (connectionStringSettings == null)
            {
                connectionStringSettings = new ConnectionStringSettings
                {
                    Name = connectionStringName
                };

                config.ConnectionStrings
                .ConnectionStrings
                .Add(connectionStringSettings);
            }

            // Add in the new connection string
            connectionStringSettings.ProviderName     = providerInvariant;
            connectionStringSettings.ConnectionString = FixUpConnectionString(connectionString, providerInvariant);

            project.DTE.SourceControl.CheckOutItemIfNeeded(configFilePath);
            config.Save();

            // Add any new file to the project
            project.ProjectItems.AddFromFile(configFilePath);
        }
        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);
        }
        private ConnectionStringSettings GetConnectionStringSettingsFromConfigFile(Project project)
        {
            // Find App.config or Web.config
            var configFilePath = Path.Combine(
                project.GetProjectDir(),
                project.IsWebProject()
                    ? "Web.config"
                    : "App.config");

            // Either load up the existing file or create a blank file
            var connectionStringSettings = ConfigurationManager
                                           .OpenMappedExeConfiguration(new ExeConfigurationFileMap {
                ExeConfigFilename = configFilePath
            }, ConfigurationUserLevel.None)
                                           .ConnectionStrings
                                           .ConnectionStrings
                                           .Cast <ConnectionStringSettings>()
                                           .FirstOrDefault(p => p.Name.ToLower().EndsWith("context"));

            return(connectionStringSettings);
        }
        private static IEnumerable <ConnectionStringSettings> GetConnectionstrings(Project project)
        {
            // Find App.config or Web.config
            var configFilePath = Path.Combine(
                project.GetProjectDir(),
                project.IsWebProject()
                    ? "Web.config"
                    : "App.config");

            // Either load up the existing file or create a blank file
            var config = ConfigurationManager.OpenMappedExeConfiguration(
                new ExeConfigurationFileMap {
                ExeConfigFilename = configFilePath
            },
                ConfigurationUserLevel.None);

            // Find or create the connectionStrings section
            var connectionStrings = config.ConnectionStrings
                                    .ConnectionStrings
                                    .Cast <ConnectionStringSettings>()
                                    .Where(x => !x.Name.Equals("localsqlserver", StringComparison.InvariantCultureIgnoreCase));

            return(connectionStrings);
        }
        public void ReverseEngineerCodeFirstMain(Project project)
        {
            DebugCheck.NotNull(project);
            targetProject = project;

            try
            {
                var startTime = DateTime.Now;

                var _storeMetadataFilters = new List <EntityStoreSchemaFilterEntry>
                {
                    new EntityStoreSchemaFilterEntry(null, null, "EdmMetadata", EntityStoreSchemaFilterObjectTypes.Table, EntityStoreSchemaFilterEffect.Exclude),
                    new EntityStoreSchemaFilterEntry(null, null, "__MigrationHistory", EntityStoreSchemaFilterObjectTypes.Table, EntityStoreSchemaFilterEffect.Exclude),
                    new EntityStoreSchemaFilterEntry(null, null, "sysdiagrams", EntityStoreSchemaFilterObjectTypes.Table, EntityStoreSchemaFilterEffect.Exclude),
                    //new EntityStoreSchemaFilterEntry(null, null, null, EntityStoreSchemaFilterObjectTypes.View, EntityStoreSchemaFilterEffect.Exclude),
                    new EntityStoreSchemaFilterEntry(null, null, null, EntityStoreSchemaFilterObjectTypes.Function, EntityStoreSchemaFilterEffect.Exclude)
                };

                //build.txt不存在或者空文本生成所有实体,有文本按设置生成
                var buildFilename = Path.Combine(targetProject.GetProjectDir(), "build.txt");
                if (File.Exists(buildFilename))
                {
                    var content = File.ReadAllText(buildFilename);
                    if (!string.IsNullOrWhiteSpace(content))
                    {
                        var allowFilterEntrys = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                                                .Select(p => new EntityStoreSchemaFilterEntry(null, null, p, EntityStoreSchemaFilterObjectTypes.Table, EntityStoreSchemaFilterEffect.Allow));

                        _storeMetadataFilters.AddRange(allowFilterEntrys);
                    }
                }

                var connectionStringSettings = DoConnectionStringSettings(targetProject);
                var entityFrameworkVersion   = GetEntityFrameworkVersion(package, targetProject);

                // Load store schema
                var storeGenerator = new EntityStoreSchemaGenerator(connectionStringSettings.ProviderName, connectionStringSettings.ConnectionString, "dbo");
                storeGenerator.GenerateForeignKeyProperties = true;
                var errors = storeGenerator.GenerateStoreMetadata(_storeMetadataFilters).Where(e => e.Severity == EdmSchemaErrorSeverity.Error);
                errors.HandleErrors(Strings.ReverseEngineer_SchemaError);

                if (storeGenerator.EntityContainer.BaseEntitySets == null || storeGenerator.EntityContainer.BaseEntitySets.Count() == 0)
                {
                    package.LogError("生成中断,没有找到对应的表", new Exception("生成中断,没有找到对应的表"));
                    return;
                }

                // Generate default mapping
                package.LogInfo(Strings.ReverseEngineer_GenerateMapping);
                var modelGenerator = new EntityModelSchemaGenerator(storeGenerator.EntityContainer, "DefaultNamespace", connectionStringSettings.Name);
                modelGenerator.PluralizationService         = PluralizationService.CreateService(new CultureInfo("en"));
                modelGenerator.GenerateForeignKeyProperties = true;
                modelGenerator.GenerateMetadata();

                var entityTypes = modelGenerator.EdmItemCollection.OfType <EntityType>().ToArray();
                EdmPropertyExtension.ColumnModels = new DocumentionExtension().GenerateDocumentation(entityTypes, connectionStringSettings);
                EntityTypeExtension.GetTableDescriptions(connectionStringSettings);

                var solutionProjects = targetProject.DTE.Solution.Projects.OfType <Project>();

                Action <IEnumerable <Project> > loopProjectsAction = null;
                loopProjectsAction = projects =>
                {
                    foreach (var item in projects)
                    {
                        if (item.FullName.EndsWith(".csproj"))
                        {
                            ReverseEngineerCodeFirst(item, modelGenerator, entityTypes, storeGenerator.StoreItemCollection, entityFrameworkVersion);
                            continue;
                        }

                        if (item.ProjectItems.Count > 0)
                        {
                            var subProjects = new List <Project>();
                            foreach (EnvDTE.ProjectItem subProject in item.ProjectItems)
                            {
                                subProjects.Add(subProject.SubProject);
                            }

                            loopProjectsAction(subProjects);
                        }
                    }
                };
                loopProjectsAction(solutionProjects);

                var duration = DateTime.Now - startTime;
                package.LogInfo(Strings.ReverseEngineer_Complete(duration.ToString(@"h\:mm\:ss")));
            }
            catch (Exception exception)
            {
                package.LogError(exception.Message, exception);
            }
        }
        public void ReverseEngineerCodeFirst(Project project, EntityModelSchemaGenerator modelGenerator, EntityType[] entityTypes, StoreItemCollection StoreItemCollection, Version entityFrameworkVersion)
        {
            DebugCheck.NotNull(project);

            try
            {
                var mappings         = new EdmMapping(modelGenerator, StoreItemCollection);
                var projectNamespace = (string)project.Properties.Item("RootNamespace").Value;

                var reverseEngineerCodeFirstFolder = new DirectoryInfo(Path.Combine(project.GetProjectDir(), "CodeTemplates", "ReverseEngineerCodeFirst"));
                if (!reverseEngineerCodeFirstFolder.Exists)
                {
                    return;
                }

                var t4Files = reverseEngineerCodeFirstFolder.GetFiles().Where(p => p.Extension == ".tt");
                if (!t4Files.Any())
                {
                    return;
                }

                // Generate Entity Classes and Mappings
                var templateProcessor = new TemplateProcessor(project);
                foreach (var file in t4Files)
                {
                    if (file.Length == 0)
                    {
                        continue;
                    }

                    #region 特殊处理Context
                    if (file.Name.ToLower().EndsWith("context.tt"))
                    {
                        package.LogInfo("Context");

                        var contextHost = new EfTextTemplateHost
                        {
                            EntityContainer        = modelGenerator.EntityContainer,
                            Namespace              = projectNamespace,
                            EntityFrameworkVersion = entityFrameworkVersion
                        };

                        SaveProjectFile(project, contextHost, templateProcessor, modelGenerator.EntityContainer.Name.Replace("Context", ""), "Models", "Context.tt");
                        continue;
                    }
                    #endregion

                    #region 实体处理
                    var fileName = file.Name.Replace(".tt", "");
                    fileName = fileName.EndsWith("s") ? fileName : fileName + "s";

                    foreach (var entityType in entityTypes)
                    {
                        package.LogInfo(file.FullName + "|" + entityType.Name);

                        var efHost = new EfTextTemplateHost
                        {
                            EntityType             = entityType,
                            EntityContainer        = modelGenerator.EntityContainer,
                            Namespace              = projectNamespace,
                            EntityFrameworkVersion = entityFrameworkVersion,
                            TableSet = mappings.EntityMappings[entityType].Item1,
                            PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2,
                            ManyToManyMappings       = mappings.ManyToManyMappings
                        };

                        SaveProjectFile(project, efHost, templateProcessor, entityType.Name, fileName, file.Name);
                    }
                    #endregion
                }
            }
            catch (Exception exception)
            {
                package.LogError(project.Name + "生成出错", exception);
            }
        }
        private static void AddConnectionStringToConfigFile(Project project, string connectionString, string providerInvariant, string connectionStringName)
        {
            DebugCheck.NotNull(project);
            DebugCheck.NotEmpty(providerInvariant);
            DebugCheck.NotEmpty(connectionStringName);

            // Find App.config or Web.config
            var configFilePath = Path.Combine(
                project.GetProjectDir(),
                project.IsWebProject()
                    ? "Web.config"
                    : "App.config");

            // Either load up the existing file or create a blank file
            var config = ConfigurationManager.OpenMappedExeConfiguration(
                new ExeConfigurationFileMap { ExeConfigFilename = configFilePath },
                ConfigurationUserLevel.None);

            // Find or create the connectionStrings section
            var connectionStringSettings = config.ConnectionStrings
                .ConnectionStrings
                .Cast<ConnectionStringSettings>()
                .FirstOrDefault(css => css.Name == connectionStringName);

            if (connectionStringSettings == null)
            {
                connectionStringSettings = new ConnectionStringSettings
                    {
                        Name = connectionStringName
                    };

                config.ConnectionStrings
                    .ConnectionStrings
                    .Add(connectionStringSettings);
            }

            // Add in the new connection string
            connectionStringSettings.ProviderName = providerInvariant;
            connectionStringSettings.ConnectionString = FixUpConnectionString(connectionString, providerInvariant);

            project.DTE.SourceControl.CheckOutItemIfNeeded(configFilePath);
            config.Save();

            // Add any new file to the project
            project.ProjectItems.AddFromFile(configFilePath);
        }