public virtual IEnumerable <string> ReverseEngineer( [NotNull] string providerAssemblyName, [NotNull] string connectionString, [NotNull] string rootNamespace, [NotNull] string projectDir) { Check.NotNull(providerAssemblyName, nameof(providerAssemblyName)); Check.NotEmpty(connectionString, nameof(connectionString)); Check.NotEmpty(rootNamespace, nameof(rootNamespace)); Check.NotEmpty(projectDir, nameof(projectDir)); var assembly = Assembly.Load(new AssemblyName(providerAssemblyName)); if (assembly == null) { throw new InvalidOperationException(Strings.CannotFindAssembly(providerAssemblyName)); } var configuration = new ReverseEngineeringConfiguration() { ProviderAssembly = assembly, ConnectionString = connectionString, Namespace = rootNamespace, OutputPath = projectDir }; var generator = new ReverseEngineeringGenerator(_serviceProvider); return(generator.GenerateAsync(configuration).Result); }
public void E2ETest() { // set current cultures to English because expected results for error messages // (both those output to the Logger and those put in comments in the .cs files) // are in English #if DNXCORE50 CultureInfo.CurrentCulture = new CultureInfo("en-US"); CultureInfo.CurrentUICulture = new CultureInfo("en-US"); #else Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); #endif var assembly = Assembly.Load(new AssemblyName(DatabaseTool._defaultReverseEngineeringProviderAssembly)); var configuration = new ReverseEngineeringConfiguration { ProviderAssembly = assembly, ConnectionString = E2EConnectionString, Namespace = TestNamespace, OutputPath = TestOutputDir }; var serviceProvider = SetupServiceProvider(); var fileService = new InMemoryFileService(); serviceProvider.AddService(typeof(IFileService), fileService); var logger = new InMemoryCommandLogger("E2ETest"); serviceProvider.AddService(typeof(ILogger), logger); var expectedFileContents = InitializeExpectedFileContents(); var generator = new ReverseEngineeringGenerator(serviceProvider); var filePaths = generator.GenerateAsync(configuration).Result; Assert.Equal(_E2ETestExpectedWarnings.Count, logger.WarningMessages.Count); // loop over warnings instead of using the collection form of Assert.Equal() // to give better error messages if it does fail. Similarly for file paths below. var i = 0; foreach (var expectedWarning in _E2ETestExpectedWarnings) { Assert.Equal(expectedWarning, logger.WarningMessages[i++]); } Assert.Equal(0, logger.InformationMessages.Count); Assert.Equal(0, logger.VerboseMessages.Count); var expectedFilePaths = _E2ETestExpectedFileNames.Select(name => TestOutputDir + @"\" + name); Assert.Equal(expectedFilePaths.Count(), filePaths.Count); i = 0; foreach (var expectedFilePath in expectedFilePaths) { Assert.Equal(expectedFilePath, filePaths[i++]); } foreach (var fileName in _E2ETestExpectedFileNames) { var fileContents = fileService.RetrieveFileContents(TestOutputDir, fileName); Assert.Equal(expectedFileContents[fileName], fileContents); } }
public async Task <SchemaResult> GetSchemaSource(string connectionString, string assemblyNamespace, bool withUsings = true) { var programName = "Ctx"; // append guid to create unique output location var outputPath = System.IO.Path.Combine(_tempFolder, Guid.NewGuid().ToIdentifierWithPrefix("folder")); var conf = new ReverseEngineeringConfiguration { ConnectionString = connectionString, ContextClassName = programName, ProjectPath = "na", ProjectRootNamespace = assemblyNamespace, OutputPath = outputPath }; ReverseEngineerFiles resFiles = null; try { // todo there's a race condition in here when fx both template and execute are called at once, // which seems to trigger something in EF, instead of this lock, do some sync in SchemaSource. lock (_lock) { var resFilesTask = Generator.GenerateAsync(conf); resFilesTask.Wait(); resFiles = resFilesTask.Result; } } catch (Exception exn) when(exn.ExpectedError()) { Logger.Debug("Known error {0}", exn.Message); return(new SchemaResult { Code = exn.StatusCode(), Message = exn.Message }); } catch (Exception exn) { Logger.Debug("Uknown error {0} (HResult: {1})", exn.Message, exn.HResult); throw exn; } var output = new StringBuilder(); var dbCtx = CreateContext(InMemoryFiles.RetrieveFileContents(outputPath, programName + ".cs"), isLibrary: withUsings); var ctx = dbCtx.Item1; if (!withUsings) { ctx = ctx.SkipLines(3); } else { output.Append(_refs); } // remove the entity generated warning about injected connection strings ctx = Regex.Replace(ctx, @"#warning.*", ""); output.Append(ctx); Logger.Info("ContextFile.Count {0}", resFiles.ContextFile.Count()); foreach (var fpath in resFiles.EntityTypeFiles) { output.Append(InMemoryFiles.RetrieveFileContents(outputPath, System.IO.Path.GetFileName(fpath)).SkipLines(4)); } return(new SchemaResult { Schema = output.ToString(), DefaultTable = dbCtx.Item2 }); }
public string GetSchemaSource(string connectionString, string assemblyNamespace, bool withUsings = true) { var loggerFactory = new LoggerFactory().AddConsole(); var ssTypeMap = new Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerTypeMapper(); var ssDbFac = new SqlServerDatabaseModelFactory(loggerFactory: loggerFactory); var ssScaffoldFac = new SqlServerScaffoldingModelFactory( loggerFactory: loggerFactory, typeMapper: ssTypeMap, databaseModelFactory: ssDbFac ); var ssAnnotationProvider = new Microsoft.EntityFrameworkCore.Metadata.SqlServerAnnotationProvider(); var csUtils = new CSharpUtilities(); var scaffUtils = new ScaffoldingUtilities(); var confFac = new ConfigurationFactory( extensionsProvider: ssAnnotationProvider, cSharpUtilities: csUtils, scaffoldingUtilities: scaffUtils ); var fs = new InMemoryFileService(); var sb = new StringBuilderCodeWriter( fileService: fs, dbContextWriter: new DbContextWriter( scaffoldingUtilities: scaffUtils, cSharpUtilities: csUtils ), entityTypeWriter: new EntityTypeWriter(cSharpUtilities: csUtils, scaffoldingUtilities: scaffUtils) ); var rGen = new ReverseEngineeringGenerator( loggerFactory: loggerFactory, scaffoldingModelFactory: ssScaffoldFac, configurationFactory: confFac, codeWriter: sb ); var outputPath = @"C:\temp"; var programName = "Ctx"; var conf = new ReverseEngineeringConfiguration { ConnectionString = connectionString, ContextClassName = programName, ProjectPath = "na", ProjectRootNamespace = assemblyNamespace, OutputPath = outputPath }; var output = new StringBuilder(); var resFiles = rGen.GenerateAsync(conf); resFiles.Wait(); var ctx = CreateContext(fs.RetrieveFileContents(outputPath, programName + ".cs"), isLibrary: withUsings); Console.WriteLine("CreateContext", ctx); if (!withUsings) { ctx = StripHeaderLines(3, ctx); } else { output.Append(_refs); } output.Append(ctx); foreach (var fpath in resFiles.Result.EntityTypeFiles) { output.Append(StripHeaderLines(4, fs.RetrieveFileContents(outputPath, System.IO.Path.GetFileName(fpath)))); } return(output.ToString()); }