public ScaffoldedModel ScaffoldModel(ProcedureModel model, ModuleScaffolderOptions procedureScaffolderOptions, ref List <string> errors)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var result = new ScaffoldedModel();

            errors = model.Errors;

            foreach (var procedure in model.Procedures)
            {
                var name = GenerateIdentifierName(procedure, model) + "Result";

                var classContent = WriteResultClass(procedure, procedureScaffolderOptions, name);

                result.AdditionalFiles.Add(new ScaffoldedFile
                {
                    Code = classContent,
                    Path = $"{name}.cs",
                });
            }

            var dbContext = WriteProcedureDbContext(procedureScaffolderOptions, model);

            result.ContextFile = new ScaffoldedFile
            {
                Code = dbContext,
                Path = Path.GetFullPath(Path.Combine(procedureScaffolderOptions.ContextDir, procedureScaffolderOptions.ContextName + "Procedures.cs")),
            };

            return(result);
        }
        private string WriteResultClass(Procedure storedProcedure, ModuleScaffolderOptions options, string name)
        {
            var @namespace = options.ModelNamespace;

            _sb = new IndentedStringBuilder();

            _sb.AppendLine(PathHelper.Header);
            _sb.AppendLine("using System;");
            _sb.AppendLine("using System.Collections.Generic;");
            _sb.AppendLine("using System.ComponentModel.DataAnnotations.Schema;");
            _sb.AppendLine();

            if (options.NullableReferences)
            {
                _sb.AppendLine("#nullable enable");
                _sb.AppendLine();
            }

            _sb.AppendLine($"namespace {@namespace}");
            _sb.AppendLine("{");

            using (_sb.Indent())
            {
                GenerateClass(storedProcedure, name, options.NullableReferences);
            }

            _sb.AppendLine("}");

            return(_sb.ToString());
        }
        private static List <string> CreateUsings(ModuleScaffolderOptions scaffolderOptions, RoutineModel model)
        {
            var usings = new List <string>()
            {
                "using Microsoft.EntityFrameworkCore",
                "using Microsoft.Data.SqlClient",
                "using System",
                "using System.Collections.Generic",
                "using System.Data",
                "using System.Threading",
                "using System.Threading.Tasks",
                $"using {scaffolderOptions.ModelNamespace}",
            };

            if (model.Routines.Any(r => r.SupportsMultipleResultSet))
            {
                usings.AddRange(new List <string>()
                {
                    "using Dapper",
                    "using Microsoft.EntityFrameworkCore.Storage",
                    "using System.Linq",
                });
            }

            if (model.Routines.SelectMany(r => r.Parameters).Any(p => p.ClrType() == typeof(Geometry)))
            {
                usings.AddRange(new List <string>()
                {
                    "using NetTopologySuite.Geometries",
                });
            }

            usings.Sort();
            return(usings);
        }
        private string WriteFunctionsClass(ModuleScaffolderOptions procedureScaffolderOptions, FunctionModel model)
        {
            _sb = new IndentedStringBuilder();

            _sb.AppendLine(PathHelper.Header);

            _sb.AppendLine("using Microsoft.EntityFrameworkCore;");
            _sb.AppendLine("using System;");

            _sb.AppendLine();
            _sb.AppendLine($"namespace {procedureScaffolderOptions.ContextNamespace}");
            _sb.AppendLine("{");

            using (_sb.Indent())
            {
                _sb.AppendLine($"public partial class {procedureScaffolderOptions.ContextName}");

                _sb.AppendLine("{");

                using (_sb.Indent())
                {
                    foreach (var function in model.Functions)
                    {
                        GenerateFunctionStub(function, model);
                    }
                }
                _sb.AppendLine("}");
            }

            _sb.AppendLine("}");

            return(_sb.ToString());
        }
        public ScaffoldedModel ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, ref List <string> errors)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var result = new ScaffoldedModel();

            errors = model.Errors;

            foreach (var routine in model.Routines.Where(r => !(r is Function f) || !f.IsScalar))
            {
                int i = 1;

                foreach (var resultSet in routine.Results)
                {
                    var suffix = string.Empty;
                    if (routine.Results.Count > 1)
                    {
                        suffix = $"{i++}";
                    }

                    var typeName = GenerateIdentifierName(routine, model) + "Result" + suffix;

                    var classContent = WriteResultClass(resultSet, scaffolderOptions, typeName);

                    result.AdditionalFiles.Add(new ScaffoldedFile
                    {
                        Code = classContent,
                        Path = scaffolderOptions.UseSchemaFolders
                                ? Path.Combine(routine.Schema, $"{typeName}.cs")
                                : $"{typeName}.cs"
                    });
                }
            }

            var dbContext = WriteDbContext(scaffolderOptions, model);

            var fileNameSuffix = this switch
            {
                SqlServerStoredProcedureScaffolder _ => "Procedures",
                SqlServerFunctionScaffolder _ => ".Functions",
                _ => throw new InvalidOperationException($"Unknown type '{GetType().Name}'"),
            };

            result.ContextFile = new ScaffoldedFile
            {
                Code = dbContext,
                Path = Path.GetFullPath(Path.Combine(scaffolderOptions.ContextDir, scaffolderOptions.ContextName + $"{fileNameSuffix}.cs")),
            };

            return(result);
        }
Ejemplo n.º 6
0
        public SavedModelFiles GenerateFunctions(
            ReverseEngineerCommandOptions options,
            ref List <string> errors,
            string outputContextDir,
            string modelNamespace,
            string contextNamespace,
            bool supportsFunctions)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var functionModelScaffolder = functionScaffolder;

            if (functionModelScaffolder != null &&
                supportsFunctions &&
                (options.Tables.Any(t => t.ObjectType == ObjectType.ScalarFunction) ||
                 !options.Tables.Any()))
            {
                var modelFactoryOptions = new ModuleModelFactoryOptions
                {
                    FullModel = true,
                    Modules   = options.Tables.Where(t => t.ObjectType == ObjectType.ScalarFunction).Select(m => m.Name),
                };

                var functionModel = functionModelFactory.Create(options.Dacpac ?? options.ConnectionString, modelFactoryOptions);

                ApplyRenamers(functionModel.Routines, options.CustomReplacers);

                var functionOptions = new ModuleScaffolderOptions
                {
                    ContextDir         = outputContextDir,
                    ContextName        = options.ContextClassName,
                    ContextNamespace   = contextNamespace,
                    ModelNamespace     = modelNamespace,
                    NullableReferences = options.UseNullableReferences,
                    UseAsyncCalls      = options.UseAsyncCalls,
                };

                var functionScaffoldedModel = functionModelScaffolder.ScaffoldModel(functionModel, functionOptions, ref errors);

                if (functionScaffoldedModel != null)
                {
                    return(functionModelScaffolder.Save(
                               functionScaffoldedModel,
                               Path.GetFullPath(Path.Combine(options.ProjectPath, options.OutputPath ?? string.Empty)),
                               contextNamespace,
                               options.UseAsyncCalls));
                }
            }

            return(null);
        }
Ejemplo n.º 7
0
        protected override string WriteDbContext(ModuleScaffolderOptions scaffolderOptions, RoutineModel model)
        {
            if (scaffolderOptions is null)
            {
                throw new ArgumentNullException(nameof(scaffolderOptions));
            }

            if (model is null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            Sb = new IndentedStringBuilder();

            Sb.AppendLine(PathHelper.Header);

            Sb.AppendLine("using Microsoft.EntityFrameworkCore;");
            Sb.AppendLine("using System;");
            Sb.AppendLine("using System.Data;");
            Sb.AppendLine("using System.Linq;");
            Sb.AppendLine($"using {scaffolderOptions.ModelNamespace};");
            if (model.Routines.SelectMany(r => r.Parameters).Any(p => p.ClrType() == typeof(Geometry)))
            {
                Sb.AppendLine("using NetTopologySuite.Geometries;");
            }

            Sb.AppendLine();
            Sb.AppendLine($"namespace {scaffolderOptions.ContextNamespace}");
            Sb.AppendLine("{");

            using (Sb.Indent())
            {
                Sb.AppendLine($"public partial class {scaffolderOptions.ContextName}");

                Sb.AppendLine("{");

                using (Sb.Indent())
                {
                    foreach (var function in model.Routines)
                    {
                        GenerateFunctionStub(function, model);
                    }

                    GenerateModelCreation(model);
                }

                Sb.AppendLine("}");
            }

            Sb.AppendLine("}");

            return(Sb.ToString());
        }
        private string WriteProcedureDbContext(ModuleScaffolderOptions procedureScaffolderOptions, ProcedureModel model)
        {
            _sb = new IndentedStringBuilder();

            _sb.AppendLine(PathHelper.Header);

            _sb.AppendLine("using Microsoft.EntityFrameworkCore;");
            _sb.AppendLine("using Microsoft.Data.SqlClient;");
            _sb.AppendLine("using System;");
            _sb.AppendLine("using System.Data;");
            _sb.AppendLine("using System.Threading;");
            _sb.AppendLine("using System.Threading.Tasks;");
            _sb.AppendLine($"using {procedureScaffolderOptions.ModelNamespace};");

            _sb.AppendLine();
            _sb.AppendLine($"namespace {procedureScaffolderOptions.ContextNamespace}");
            _sb.AppendLine("{");

            using (_sb.Indent())
            {
                _sb.AppendLine($"public partial class {procedureScaffolderOptions.ContextName}Procedures");

                _sb.AppendLine("{");

                using (_sb.Indent())
                {
                    _sb.AppendLine($"private readonly {procedureScaffolderOptions.ContextName} _context;");
                    _sb.AppendLine();
                    _sb.AppendLine($"public {procedureScaffolderOptions.ContextName}Procedures({procedureScaffolderOptions.ContextName} context)");
                    _sb.AppendLine("{");

                    using (_sb.Indent())
                    {
                        _sb.AppendLine($"_context = context;");
                    }

                    _sb.AppendLine("}");
                }

                foreach (var procedure in model.Procedures)
                {
                    GenerateProcedure(procedure, model);
                }

                _sb.AppendLine("}");
            }

            _sb.AppendLine("}");

            return(_sb.ToString());
        }
Ejemplo n.º 9
0
        public static SavedModelFiles GenerateStoredProcedures(
            ReverseEngineerCommandOptions options,
            ref List <string> errors,
            ServiceProvider serviceProvider,
            string outputContextDir,
            string modelNamespace,
            string contextNamespace)
        {
            var procedureModelScaffolder = serviceProvider.GetService <IProcedureScaffolder>();

            if (procedureModelScaffolder != null &&
                (options.Tables.Any(t => t.ObjectType == ObjectType.Procedure) ||
                 !options.Tables.Any()))
            {
                var procedureModelFactory = serviceProvider.GetService <IProcedureModelFactory>();

                var procedureModelFactoryOptions = new ModuleModelFactoryOptions
                {
                    DiscoverMultipleResultSets = options.UseMultipleSprocResultSets,
                    FullModel = true,
                    Modules   = options.Tables.Where(t => t.ObjectType == ObjectType.Procedure).Select(m => m.Name),
                };

                var procedureModel = procedureModelFactory.Create(options.Dacpac ?? options.ConnectionString, procedureModelFactoryOptions);

                ApplyRenamers(procedureModel.Routines, options.CustomReplacers);

                var procedureOptions = new ModuleScaffolderOptions
                {
                    ContextDir         = outputContextDir,
                    ContextName        = options.ContextClassName,
                    ContextNamespace   = contextNamespace,
                    ModelNamespace     = modelNamespace,
                    NullableReferences = options.UseNullableReferences,
                    UseSchemaFolders   = options.UseSchemaFolders,
                };

                var procedureScaffoldedModel = procedureModelScaffolder.ScaffoldModel(procedureModel, procedureOptions, ref errors);

                if (procedureScaffoldedModel != null)
                {
                    return(procedureModelScaffolder.Save(
                               procedureScaffoldedModel,
                               Path.GetFullPath(Path.Combine(options.ProjectPath, options.OutputPath ?? string.Empty)),
                               contextNamespace));
                }
            }

            return(null);
        }
        public static SavedModelFiles GenerateFunctions(
            ReverseEngineerCommandOptions options,
            ref List <string> errors,
            ServiceProvider serviceProvider,
            string outputContextDir,
            string modelNamespace,
            string contextNamespace)
        {
            var functionModelScaffolder = serviceProvider.GetService <IFunctionScaffolder>();

            if (functionModelScaffolder != null &&
                (options.Tables.Any(t => t.ObjectType == ObjectType.ScalarFunction) ||
                 !options.Tables.Any()))
            {
                var functionModelFactory = serviceProvider.GetService <IFunctionModelFactory>();

                var modelFactoryOptions = new ModuleModelFactoryOptions
                {
                    FullModel = true,
                    Modules   = options.Tables.Where(t => t.ObjectType == ObjectType.ScalarFunction).Select(m => m.Name),
                };

                var functionModel = functionModelFactory.Create(options.Dacpac ?? options.ConnectionString, modelFactoryOptions);

                ApplyRenamers(functionModel.Functions, options.CustomReplacers);

                var functionOptions = new ModuleScaffolderOptions
                {
                    ContextDir         = outputContextDir,
                    ContextName        = options.ContextClassName,
                    ContextNamespace   = contextNamespace,
                    ModelNamespace     = modelNamespace,
                    NullableReferences = options.UseNullableReferences,
                };

                var functionScaffoldedModel = functionModelScaffolder.ScaffoldModel(functionModel, functionOptions, ref errors);

                if (functionScaffoldedModel != null)
                {
                    return(functionModelScaffolder.Save(
                               functionScaffoldedModel,
                               Path.GetFullPath(Path.Combine(options.ProjectPath, options.OutputPath ?? string.Empty)),
                               contextNamespace));
                }
            }

            return(null);
        }
        protected override string WriteDbContextInterface(ModuleScaffolderOptions scaffolderOptions, RoutineModel model)
        {
            if (scaffolderOptions is null)
            {
                throw new ArgumentNullException(nameof(scaffolderOptions));
            }

            if (model is null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            Sb = new IndentedStringBuilder();

            Sb.AppendLine(PathHelper.Header);

            var usings = CreateUsings(scaffolderOptions, model);

            foreach (var statement in usings)
            {
                Sb.AppendLine($"{statement};");
            }

            Sb.AppendLine();
            Sb.AppendLine($"namespace {scaffolderOptions.ContextNamespace}");
            Sb.AppendLine("{");

            using (Sb.Indent())
            {
                Sb.AppendLine($"public partial interface I{scaffolderOptions.ContextName}Procedures");
                Sb.AppendLine("{");
                using (Sb.Indent())
                {
                    foreach (var procedure in model.Routines)
                    {
                        GenerateProcedure(procedure, model, true, scaffolderOptions.UseAsyncCalls);
                        Sb.AppendLine(";");
                    }
                }

                Sb.AppendLine("}");
            }

            Sb.AppendLine("}");

            return(Sb.ToString());
        }
        public ScaffoldedModel ScaffoldModel(FunctionModel model, ModuleScaffolderOptions scaffolderOptions, ref List <string> errors)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var result = new ScaffoldedModel();

            errors = model.Errors;

            var dbContext = WriteFunctionsClass(scaffolderOptions, model);

            result.ContextFile = new ScaffoldedFile
            {
                Code = dbContext,
                Path = Path.GetFullPath(Path.Combine(scaffolderOptions.ContextDir, scaffolderOptions.ContextName + ".Functions.cs")),
            };

            return(result);
        }
Ejemplo n.º 13
0
        protected override string WriteDbContext(ModuleScaffolderOptions scaffolderOptions, RoutineModel model)
        {
            _sb = new IndentedStringBuilder();

            _sb.AppendLine(PathHelper.Header);

            _sb.AppendLine("using Microsoft.EntityFrameworkCore;");
            _sb.AppendLine("using System;");
            _sb.AppendLine("using System.Linq;");
            _sb.AppendLine($"using {scaffolderOptions.ModelNamespace};");

            _sb.AppendLine();
            _sb.AppendLine($"namespace {scaffolderOptions.ContextNamespace}");
            _sb.AppendLine("{");

            using (_sb.Indent())
            {
                _sb.AppendLine($"public partial class {scaffolderOptions.ContextName}");

                _sb.AppendLine("{");

                using (_sb.Indent())
                {
                    foreach (var function in model.Routines)
                    {
                        GenerateFunctionStub(function, model);
                    }

                    GenerateModelCreation(model);
                }
                _sb.AppendLine("}");
            }

            _sb.AppendLine("}");

            return(_sb.ToString());
        }
        private string WriteResultClass(List <ModuleResultElement> resultElements, ModuleScaffolderOptions options, string name)
        {
            var @namespace = options.ModelNamespace;

            Sb = new IndentedStringBuilder();

            Sb.AppendLine(PathHelper.Header);

            if (resultElements.Any(p => p.ClrType() == typeof(Geometry)))
            {
                Sb.AppendLine("using NetTopologySuite.Geometries;");
            }

            Sb.AppendLine("using System;");
            Sb.AppendLine("using System.Collections.Generic;");
            Sb.AppendLine("using System.ComponentModel.DataAnnotations.Schema;");
            Sb.AppendLine();

            if (options.NullableReferences)
            {
                Sb.AppendLine("#nullable enable");
                Sb.AppendLine();
            }

            Sb.AppendLine($"namespace {@namespace}");
            Sb.AppendLine("{");

            using (Sb.Indent())
            {
                GenerateClass(resultElements, name, options.NullableReferences);
            }

            Sb.AppendLine("}");

            return(Sb.ToString());
        }
 public ScaffoldedModel ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, ref List <string> errors)
 {
     throw new NotSupportedException();
 }
        protected override string WriteDbContext(ModuleScaffolderOptions scaffolderOptions, RoutineModel model)
        {
            if (scaffolderOptions is null)
            {
                throw new ArgumentNullException(nameof(scaffolderOptions));
            }

            if (model is null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            Sb = new IndentedStringBuilder();

            Sb.AppendLine(PathHelper.Header);

            var usings = CreateUsings(scaffolderOptions, model);

            foreach (var statement in usings)
            {
                Sb.AppendLine($"{statement};");
            }

            Sb.AppendLine();
            Sb.AppendLine($"namespace {scaffolderOptions.ContextNamespace}");
            Sb.AppendLine("{");

            using (Sb.Indent())
            {
                Sb.AppendLine($"public partial class {scaffolderOptions.ContextName}");
                Sb.AppendLine("{");
                using (Sb.Indent())
                {
                    Sb.AppendLine($"private I{scaffolderOptions.ContextName}Procedures _procedures;");
                    Sb.AppendLine();
                    Sb.AppendLine($"public virtual I{scaffolderOptions.ContextName}Procedures Procedures");
                    Sb.AppendLine("{");
                    using (Sb.Indent())
                    {
                        Sb.AppendLine("get");
                        Sb.AppendLine("{");
                        using (Sb.Indent())
                        {
                            Sb.AppendLine($"if (_procedures is null) _procedures = new {scaffolderOptions.ContextName}Procedures(this);");
                            Sb.AppendLine("return _procedures;");
                        }

                        Sb.AppendLine("}");
                        Sb.AppendLine("set");
                        Sb.AppendLine("{");
                        using (Sb.Indent())
                        {
                            Sb.AppendLine("_procedures = value;");
                        }

                        Sb.AppendLine("}");
                    }

                    Sb.AppendLine("}");
                    Sb.AppendLine();
                    Sb.AppendLine($"public I{scaffolderOptions.ContextName}Procedures GetProcedures()");
                    Sb.AppendLine("{");
                    using (Sb.Indent())
                    {
                        Sb.AppendLine("return Procedures;");
                    }

                    Sb.AppendLine("}");
                    GenerateOnModelCreating(model);
                }

                Sb.AppendLine("}");
                Sb.AppendLine();

                Sb.AppendLine($"public partial class {scaffolderOptions.ContextName}Procedures : I{scaffolderOptions.ContextName}Procedures");
                Sb.AppendLine("{");

                using (Sb.Indent())
                {
                    Sb.AppendLine($"private readonly {scaffolderOptions.ContextName} _context;");
                    Sb.AppendLine();
                    Sb.AppendLine($"public {scaffolderOptions.ContextName}Procedures({scaffolderOptions.ContextName} context)");
                    Sb.AppendLine("{");

                    using (Sb.Indent())
                    {
                        Sb.AppendLine($"_context = context;");
                    }

                    Sb.AppendLine("}");
                }

                foreach (var procedure in model.Routines)
                {
                    GenerateProcedure(procedure, model, false, scaffolderOptions.UseAsyncCalls);
                }

                if (model.Routines.Any(r => r.SupportsMultipleResultSet))
                {
                    GenerateDapperSupport(scaffolderOptions.UseAsyncCalls);
                }

                Sb.AppendLine("}");
            }

            Sb.AppendLine("}");

            return(Sb.ToString());
        }
Ejemplo n.º 17
0
 protected override string WriteDbContextInterface(ModuleScaffolderOptions scaffolderOptions, RoutineModel model)
 {
     return(null);
 }
Ejemplo n.º 18
0
        public SavedModelFiles GenerateStoredProcedures(
            ReverseEngineerCommandOptions options,
            ref List <string> errors,
            string outputContextDir,
            string modelNamespace,
            string contextNamespace,
            bool supportsProcedures)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var procedureModelScaffolder = procedureModelFactory;

            if (procedureModelScaffolder != null &&
                supportsProcedures &&
                (options.Tables.Any(t => t.ObjectType == ObjectType.Procedure) ||
                 !options.Tables.Any()))
            {
                var procedureModelFactoryOptions = new ModuleModelFactoryOptions
                {
                    DiscoverMultipleResultSets  = options.UseMultipleSprocResultSets,
                    UseLegacyResultSetDiscovery = options.UseLegacyResultSetDiscovery && !options.UseMultipleSprocResultSets,
                    FullModel = true,
                    Modules   = options.Tables.Where(t => t.ObjectType == ObjectType.Procedure).Select(m => m.Name),
                    ModulesUsingLegacyDiscovery = options.Tables
                                                  .Where(t => t.ObjectType == ObjectType.Procedure && t.UseLegacyResultSetDiscovery)
                                                  .Select(m => m.Name),
                    MappedModules = options.Tables
                                    .Where(t => t.ObjectType == ObjectType.Procedure && !string.IsNullOrEmpty(t.MappedType))
                                    .Select(m => new { m.Name, m.MappedType })
                                    .ToDictionary(m => m.Name, m => m.MappedType),
                };

                var procedureModel = procedureModelFactory.Create(options.Dacpac ?? options.ConnectionString, procedureModelFactoryOptions);

                ApplyRenamers(procedureModel.Routines, options.CustomReplacers);

                var procedureOptions = new ModuleScaffolderOptions
                {
                    ContextDir         = outputContextDir,
                    ContextName        = options.ContextClassName,
                    ContextNamespace   = contextNamespace,
                    ModelNamespace     = modelNamespace,
                    NullableReferences = options.UseNullableReferences,
                    UseSchemaFolders   = options.UseSchemaFolders,
                    UseAsyncCalls      = options.UseAsyncCalls,
                };

                var procedureScaffoldedModel = procedureScaffolder.ScaffoldModel(procedureModel, procedureOptions, ref errors);

                if (procedureScaffoldedModel != null)
                {
                    return(procedureScaffolder.Save(
                               procedureScaffoldedModel,
                               Path.GetFullPath(Path.Combine(options.ProjectPath, options.OutputPath ?? string.Empty)),
                               contextNamespace,
                               options.UseAsyncCalls));
                }
            }

            return(null);
        }
 protected abstract string WriteDbContext(ModuleScaffolderOptions scaffolderOptions, RoutineModel model);
        private string WriteProcedureDbContext(ModuleScaffolderOptions procedureScaffolderOptions, ProcedureModel model)
        {
            _sb = new IndentedStringBuilder();

            _sb.AppendLine(PathHelper.Header);

            _sb.AppendLine("using Microsoft.EntityFrameworkCore;");
            _sb.AppendLine("using Microsoft.Data.SqlClient;");
            _sb.AppendLine("using System;");
            _sb.AppendLine("using System.Collections.Generic;");
            //To support System.Data.DataTable
            _sb.AppendLine("using System.Data;");
            _sb.AppendLine("using System.Threading;");
            _sb.AppendLine("using System.Threading.Tasks;");
            _sb.AppendLine($"using {procedureScaffolderOptions.ModelNamespace};");

            _sb.AppendLine();
            _sb.AppendLine($"namespace {procedureScaffolderOptions.ContextNamespace}");
            _sb.AppendLine("{");

            using (_sb.Indent())
            {
                _sb.AppendLine($"public partial class {procedureScaffolderOptions.ContextName}");
                _sb.AppendLine("{");
                using (_sb.Indent())
                {
                    _sb.AppendLine($"private {procedureScaffolderOptions.ContextName}Procedures _procedures;");
                    _sb.AppendLine();
                    _sb.AppendLine($"public {procedureScaffolderOptions.ContextName}Procedures Procedures");
                    _sb.AppendLine("{");
                    using (_sb.Indent())
                    {
                        _sb.AppendLine("get");
                        _sb.AppendLine("{");
                        using (_sb.Indent())
                        {
                            _sb.AppendLine($"if (_procedures is null) _procedures = new {procedureScaffolderOptions.ContextName}Procedures(this);");
                            _sb.AppendLine("return _procedures;");
                        }
                        _sb.AppendLine("}");
                        _sb.AppendLine("set");
                        _sb.AppendLine("{");
                        using (_sb.Indent())
                        {
                            _sb.AppendLine("_procedures = value;");
                        }
                        _sb.AppendLine("}");
                    }
                    _sb.AppendLine("}");
                    _sb.AppendLine("");
                    _sb.AppendLine($"public {procedureScaffolderOptions.ContextName}Procedures GetProcedures()");
                    _sb.AppendLine("{");
                    using (_sb.Indent())
                    {
                        _sb.AppendLine("return Procedures;");
                    }
                    _sb.AppendLine("}");
                }
                _sb.AppendLine("}");
                _sb.AppendLine();

                _sb.AppendLine($"public partial class {procedureScaffolderOptions.ContextName}Procedures");
                _sb.AppendLine("{");

                using (_sb.Indent())
                {
                    _sb.AppendLine($"private readonly {procedureScaffolderOptions.ContextName} _context;");
                    _sb.AppendLine();
                    _sb.AppendLine($"public {procedureScaffolderOptions.ContextName}Procedures({procedureScaffolderOptions.ContextName} context)");
                    _sb.AppendLine("{");

                    using (_sb.Indent())
                    {
                        _sb.AppendLine($"_context = context;");
                    }

                    _sb.AppendLine("}");
                }

                foreach (var procedure in model.Procedures)
                {
                    GenerateProcedure(procedure, model);
                }

                _sb.AppendLine("}");
            }

            _sb.AppendLine("}");

            return(_sb.ToString());
        }
Ejemplo n.º 21
0
        public static ReverseEngineerResult GenerateFiles(ReverseEngineerCommandOptions reverseEngineerOptions)
        {
            var errors   = new List <string>();
            var warnings = new List <string>();
            var reporter = new OperationReporter(
                new OperationReportHandler(
                    m => errors.Add(m),
                    m => warnings.Add(m)));
            var serviceProvider = ServiceProviderBuilder.Build(reverseEngineerOptions);
            var scaffolder      = serviceProvider.GetService <IReverseEngineerScaffolder>();
            var schemas         = new List <string>();

            reverseEngineerOptions.ConnectionString = SqlServerHelper.SetConnectionString(reverseEngineerOptions.DatabaseType, reverseEngineerOptions.ConnectionString);

            if (reverseEngineerOptions.DefaultDacpacSchema != null)
            {
                schemas.Add(reverseEngineerOptions.DefaultDacpacSchema);
            }

            if (reverseEngineerOptions.FilterSchemas)
            {
                schemas.AddRange(reverseEngineerOptions.Schemas.Select(s => s.Name));
            }

            var outputDir = !string.IsNullOrEmpty(reverseEngineerOptions.OutputPath)
               ? Path.IsPathFullyQualified(reverseEngineerOptions.OutputPath)
                    ? reverseEngineerOptions.OutputPath
                    : Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath))
                : reverseEngineerOptions.ProjectPath;

            var outputContextDir = !string.IsNullOrEmpty(reverseEngineerOptions.OutputContextPath)
               ? Path.IsPathFullyQualified(reverseEngineerOptions.OutputContextPath)
                    ? reverseEngineerOptions.OutputContextPath
                    : Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputContextPath))
                : outputDir;

            var modelNamespace = !string.IsNullOrEmpty(reverseEngineerOptions.ModelNamespace)
                ? reverseEngineerOptions.ProjectRootNamespace + "." + reverseEngineerOptions.ModelNamespace
                : PathHelper.GetNamespaceFromOutputPath(outputDir, reverseEngineerOptions.ProjectPath, reverseEngineerOptions.ProjectRootNamespace);

            var contextNamespace = !string.IsNullOrEmpty(reverseEngineerOptions.ContextNamespace)
                ? reverseEngineerOptions.ProjectRootNamespace + "." + reverseEngineerOptions.ContextNamespace
                : PathHelper.GetNamespaceFromOutputPath(outputContextDir, reverseEngineerOptions.ProjectPath, reverseEngineerOptions.ProjectRootNamespace);

            SavedModelFiles procedurePaths           = null;
            var             procedureModelScaffolder = serviceProvider.GetService <IProcedureScaffolder>();

            if (procedureModelScaffolder != null &&
                reverseEngineerOptions.Tables.Any(t => t.ObjectType == ObjectType.Procedure))
            {
                var procedureModelFactory = serviceProvider.GetService <IProcedureModelFactory>();

                var procedureModelFactoryOptions = new ModuleModelFactoryOptions
                {
                    FullModel = true,
                    Modules   = reverseEngineerOptions.Tables.Where(t => t.ObjectType == ObjectType.Procedure).Select(m => m.Name),
                };

                var procedureModel = procedureModelFactory.Create(reverseEngineerOptions.Dacpac ?? reverseEngineerOptions.ConnectionString, procedureModelFactoryOptions);

                var procedureOptions = new ModuleScaffolderOptions
                {
                    ContextDir         = outputContextDir,
                    ContextName        = reverseEngineerOptions.ContextClassName,
                    ContextNamespace   = contextNamespace,
                    ModelNamespace     = modelNamespace,
                    NullableReferences = reverseEngineerOptions.UseNullableReferences,
                };

                var procedureScaffoldedModel = procedureModelScaffolder.ScaffoldModel(procedureModel, procedureOptions, ref errors);

                if (procedureScaffoldedModel != null)
                {
                    procedurePaths = procedureModelScaffolder.Save(
                        procedureScaffoldedModel,
                        Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty)),
                        contextNamespace);
                }
            }

            SavedModelFiles functionPaths           = null;
            var             functionModelScaffolder = serviceProvider.GetService <IFunctionScaffolder>();

            if (functionModelScaffolder != null &&
                reverseEngineerOptions.Tables.Any(t => t.ObjectType == ObjectType.ScalarFunction))
            {
                var functionModelFactory = serviceProvider.GetService <IFunctionModelFactory>();

                var modelFactoryOptions = new ModuleModelFactoryOptions
                {
                    FullModel = true,
                    Modules   = reverseEngineerOptions.Tables.Where(t => t.ObjectType == ObjectType.ScalarFunction).Select(m => m.Name),
                };

                var functionModel = functionModelFactory.Create(reverseEngineerOptions.Dacpac ?? reverseEngineerOptions.ConnectionString, modelFactoryOptions);

                var functionOptions = new ModuleScaffolderOptions
                {
                    ContextDir         = outputContextDir,
                    ContextName        = reverseEngineerOptions.ContextClassName,
                    ContextNamespace   = contextNamespace,
                    ModelNamespace     = modelNamespace,
                    NullableReferences = reverseEngineerOptions.UseNullableReferences,
                };

                var functionScaffoldedModel = functionModelScaffolder.ScaffoldModel(functionModel, functionOptions, ref errors);

                if (functionScaffoldedModel != null)
                {
                    functionPaths = functionModelScaffolder.Save(
                        functionScaffoldedModel,
                        Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty)),
                        contextNamespace);
                }
            }

            var modelOptions = new ModelReverseEngineerOptions
            {
                UseDatabaseNames = reverseEngineerOptions.UseDatabaseNames,
#if CORE50
                NoPluralize = !reverseEngineerOptions.UseInflector,
#endif
            };

            var codeOptions = new ModelCodeGenerationOptions
            {
                UseDataAnnotations = !reverseEngineerOptions.UseFluentApiOnly,
                Language           = "C#",
                ContextName        = reverseEngineerOptions.ContextClassName,
                ContextDir         = outputContextDir,
                RootNamespace      = null,
                ContextNamespace   = contextNamespace,
                ModelNamespace     = modelNamespace,
                SuppressConnectionStringWarning = false,
                ConnectionString = reverseEngineerOptions.ConnectionString,
#if CORE50
                SuppressOnConfiguring = !reverseEngineerOptions.IncludeConnectionString,
#endif
            };

            var dbOptions = new DatabaseModelFactoryOptions(reverseEngineerOptions.Tables.Where(t => t.ObjectType.HasColumns()).Select(m => m.Name), schemas);

            var scaffoldedModel = ScaffoldModel(
                reverseEngineerOptions.Dacpac ?? reverseEngineerOptions.ConnectionString,
                dbOptions,
                modelOptions,
                codeOptions,
                reverseEngineerOptions.UseBoolPropertiesWithoutDefaultSql,
                reverseEngineerOptions.UseNoNavigations,
                serviceProvider);

            var filePaths = scaffolder.Save(
                scaffoldedModel,
                Path.GetFullPath(Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty)),
                overwriteFiles: true);

#if CORE50
#else
            RemoveOnConfiguring(filePaths.ContextFile, reverseEngineerOptions.IncludeConnectionString);
#endif
            foreach (var file in filePaths.AdditionalFiles)
            {
                PostProcess(file);
            }

            PostProcess(filePaths.ContextFile);

            var entityTypeConfigurationPaths = SplitDbContext(filePaths.ContextFile, reverseEngineerOptions.UseDbContextSplitting, contextNamespace);

            var cleanUpPaths = new SavedModelFiles(filePaths.ContextFile, filePaths.AdditionalFiles);
            if (procedurePaths != null)
            {
                cleanUpPaths.AdditionalFiles.Add(procedurePaths.ContextFile);
                foreach (var additionalFile in procedurePaths.AdditionalFiles)
                {
                    cleanUpPaths.AdditionalFiles.Add(additionalFile);
                }
            }
            if (functionPaths != null)
            {
                cleanUpPaths.AdditionalFiles.Add(functionPaths.ContextFile);
            }

            CleanUp(cleanUpPaths, entityTypeConfigurationPaths);

            var result = new ReverseEngineerResult
            {
                EntityErrors                  = errors,
                EntityWarnings                = warnings,
                EntityTypeFilePaths           = filePaths.AdditionalFiles,
                ContextFilePath               = filePaths.ContextFile,
                ContextConfigurationFilePaths = entityTypeConfigurationPaths,
            };

            return(result);
        }
        public ScaffoldedModel ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, ref List <string> errors)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (errors == null)
            {
                throw new ArgumentNullException(nameof(errors));
            }

            if (scaffolderOptions == null)
            {
                throw new ArgumentNullException(nameof(scaffolderOptions));
            }

            var result = new ScaffoldedModel();

            errors.AddRange(model.Errors);

            foreach (var routine in model.Routines.Where(r => !(r is Function f) || !f.IsScalar))
            {
                int i = 1;

                foreach (var resultSet in routine.Results)
                {
                    if (routine.NoResultSet)
                    {
                        continue;
                    }

                    var suffix = string.Empty;
                    if (routine.Results.Count > 1)
                    {
                        suffix = $"{i++}";
                    }

                    var typeName = GenerateIdentifierName(routine, model) + "Result" + suffix;

                    var classContent = WriteResultClass(resultSet, scaffolderOptions, typeName);

                    result.AdditionalFiles.Add(new ScaffoldedFile
                    {
                        Code = classContent,
                        Path = scaffolderOptions.UseSchemaFolders
                                ? Path.Combine(routine.Schema, $"{typeName}.cs")
                                : $"{typeName}.cs",
                    });
                }
            }

            var dbContextInterface = WriteDbContextInterface(scaffolderOptions, model);

            if (!string.IsNullOrEmpty(dbContextInterface))
            {
                result.AdditionalFiles.Add(new ScaffoldedFile
                {
                    Code = dbContextInterface,
                    Path = Path.GetFullPath(Path.Combine(scaffolderOptions.ContextDir, $"I{scaffolderOptions.ContextName}Procedures.cs")),
                });
            }

            var dbContext = WriteDbContext(scaffolderOptions, model);

            result.ContextFile = new ScaffoldedFile
            {
                Code = dbContext,
                Path = Path.GetFullPath(Path.Combine(scaffolderOptions.ContextDir, scaffolderOptions.ContextName + $"{FileNameSuffix}.cs")),
            };

            return(result);
        }
        protected override string WriteDbContext(ModuleScaffolderOptions procedureScaffolderOptions, RoutineModel model)
        {
            _sb = new IndentedStringBuilder();

            _sb.AppendLine(PathHelper.Header);

            var usings = new List <string>()
            {
                "using Microsoft.EntityFrameworkCore",
                "using Microsoft.Data.SqlClient",
                "using System",
                "using System.Collections.Generic",
                "using System.Data",
                "using System.Threading",
                "using System.Threading.Tasks",
                $"using {procedureScaffolderOptions.ModelNamespace}",
            };

            if (model.Routines.Any(r => r.SupportsMultipleResultSet))
            {
                usings.AddRange(new List <string>()
                {
                    "using Dapper",
                    "using Microsoft.EntityFrameworkCore.Storage",
                    "using System.Linq",
                });
            }

            usings.Sort();

            foreach (var statement in usings)
            {
                _sb.AppendLine($"{statement};");
            }

            _sb.AppendLine();
            _sb.AppendLine($"namespace {procedureScaffolderOptions.ContextNamespace}");
            _sb.AppendLine("{");

            using (_sb.Indent())
            {
                _sb.AppendLine($"public partial class {procedureScaffolderOptions.ContextName}");
                _sb.AppendLine("{");
                using (_sb.Indent())
                {
                    _sb.AppendLine($"private {procedureScaffolderOptions.ContextName}Procedures _procedures;");
                    _sb.AppendLine();
                    _sb.AppendLine($"public virtual {procedureScaffolderOptions.ContextName}Procedures Procedures");
                    _sb.AppendLine("{");
                    using (_sb.Indent())
                    {
                        _sb.AppendLine("get");
                        _sb.AppendLine("{");
                        using (_sb.Indent())
                        {
                            _sb.AppendLine($"if (_procedures is null) _procedures = new {procedureScaffolderOptions.ContextName}Procedures(this);");
                            _sb.AppendLine("return _procedures;");
                        }
                        _sb.AppendLine("}");
                        _sb.AppendLine("set");
                        _sb.AppendLine("{");
                        using (_sb.Indent())
                        {
                            _sb.AppendLine("_procedures = value;");
                        }
                        _sb.AppendLine("}");
                    }
                    _sb.AppendLine("}");
                    _sb.AppendLine("");
                    _sb.AppendLine($"public {procedureScaffolderOptions.ContextName}Procedures GetProcedures()");
                    _sb.AppendLine("{");
                    using (_sb.Indent())
                    {
                        _sb.AppendLine("return Procedures;");
                    }
                    _sb.AppendLine("}");
                }
                _sb.AppendLine("}");
                _sb.AppendLine();

                _sb.AppendLine($"public partial class {procedureScaffolderOptions.ContextName}Procedures");
                _sb.AppendLine("{");

                using (_sb.Indent())
                {
                    _sb.AppendLine($"private readonly {procedureScaffolderOptions.ContextName} _context;");
                    _sb.AppendLine();
                    _sb.AppendLine($"public {procedureScaffolderOptions.ContextName}Procedures({procedureScaffolderOptions.ContextName} context)");
                    _sb.AppendLine("{");

                    using (_sb.Indent())
                    {
                        _sb.AppendLine($"_context = context;");
                    }

                    _sb.AppendLine("}");
                }

                foreach (var procedure in model.Routines)
                {
                    GenerateProcedure(procedure, model);
                }

                if (model.Routines.Any(r => r.SupportsMultipleResultSet))
                {
                    GenerateDapperSupport();
                }

                _sb.AppendLine("}");
            }

            _sb.AppendLine("}");

            return(_sb.ToString());
        }