示例#1
0
        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);
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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
            });
        }
示例#4
0
        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());
        }