Search code examples
c#entity-frameworkentity-framework-corepomelo-entityframeworkcore-mysql

EF core 3.1+Pomelo Scaffold-DbContext prevent view code generation


I have recently upgraded from EF core 3.0 to 3.1.1, along with the Pomelo adapter and Tools. However, after the update the Scaffold-DbContext command generates code for all views as well now.

Scaffold-DbContext -Connection name=SystemDatabase -Provider Pomelo.EntityFrameworkCore.MySql -Force -Context MyDbContext -Project Test.Data

I would like the generated DbContext to stay the same like before the update - without views (until throughoutly tested).
How can I disable this new view-generating feature?


Solution

  • Currently, this feature is not implemented in EF Core. However, it is being tracked on GitHub.

    1 General solution

    The only official way to accomplish what you want, is to use the -t command line argument (or -Tables, depending on the tool) for every single table you want to scaffold (and thereby ignoring all views):

    1.1 dotnet ef scaffold

    dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb; Database=Blogging; Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Models -t Blog -t Post --context-dir Context -c BlogContext --context-namespace New.Namespace

    1.2 Scaffold-DbContext

    Scaffold-DbContext "Server=(localdb)\mssqllocaldb; Database=Blogging; Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables "Blog","Post" -ContextDir Context -Context BlogContext -ContextNamespace New.Namespace

    2 Provider specific solution

    You can also derive your own custom scaffolder from MySqlDatabaseModelFactory and supply all the tables of the database automatically, so you don't have to specify them one-by-one:

    using System.Collections.Generic;
    using System.Diagnostics;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Design;
    using Microsoft.EntityFrameworkCore.Diagnostics;
    using Microsoft.EntityFrameworkCore.Scaffolding;
    using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
    using Microsoft.Extensions.DependencyInjection;
    using MySql.Data.MySqlClient;
    using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal;
    using Pomelo.EntityFrameworkCore.MySql.Scaffolding.Internal;
    
    #pragma warning disable EF1001
    
    namespace IssueConsoleTemplate
    {
        public class CustomMySqlDesignTimeServices : IDesignTimeServices
        {
            public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
                => serviceCollection
                     .AddSingleton<IDatabaseModelFactory, CustomMySqlDatabaseModelFactory>();
        }
    
        public class CustomMySqlDatabaseModelFactory : MySqlDatabaseModelFactory
        {
            public CustomMySqlDatabaseModelFactory(
                IDiagnosticsLogger<DbLoggerCategory.Scaffolding> logger,
                IMySqlOptions options)
                : base(logger, options)
            {
            }
            
            public override DatabaseModel Create(
                string connectionString,
                DatabaseModelFactoryOptions options)
            {
                //Debugger.Launch();
                
                var tables = new HashSet<string>();
                
                using (var connection = new MySqlConnection(connectionString))
                {
                    connection.Open();
                    
                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = @"SELECT `TABLE_NAME`
    FROM `INFORMATION_SCHEMA`.`TABLES`
    WHERE `TABLE_SCHEMA` = SCHEMA() AND `TABLE_TYPE` = 'BASE TABLE';";
    
                        using (var dataReader = command.ExecuteReader())
                        {
                            while (dataReader.Read())
                            {
                                tables.Add(dataReader.GetString("TABLE_NAME"));
                            }
                        }
                    }
                }
                
                return base.Create(
                    connectionString,
                    new DatabaseModelFactoryOptions(tables));
            }
        }
    
        internal static class Program
        {
            private static void Main()
            {
            }
        }
    }
    

    3 Pomelo 3.2.0+ solution using a connection string option

    We just added an issue and a PR on our GitHub repository for this feature.

    It will be part of the 3.2.0 release and also be available from our nightly build feed in approximately 24 hours.

    It introduces a Pomelo and scaffolding specific connection string option Scaffold:Views=off, that can be set as part of the command line:

    dotnet ef dbcontext scaffold "server=127.0.0.1; uid=root; pwd=; database=So62830251; Scaffold:Views=off" Pomelo.EntityFrameworkCore.MySql -c Context