2

I'm making a .NET Core console application using VS 2019. I use EF Scaffolding using de NuGet console. In a MVC project I use the following command:

Scaffold-DbContext Name=ConnectionStrings:ClientConnection ....

Note that I use the alias that exists in the appesetting.json so that I don't explicitly put the database credentials in the command (for good practices purposes). Anyway this works in a MVC project as I said, but in a console app it does not accept the alias, I get the following error:

"A named connection string was used, but the name 'ConnectionStrings:ClientConnection' was not found in the application's configuration. Note that named connection strings are only supported when using 'IConfiguration' and a service provider, such as in a typical ASP.NET Core application. See https://go.microsoft.com/fwlink/?linkid=850912 for more information."

I have to explicitly add the connection string with everything so that it works.

How can I use the scaffold command using the "Name=ConnectionStrings:ClientConnection" without any problem in a .NET Core Console Application?

Luis Frediani
  • 113
  • 1
  • 2
  • 7
  • Can you share some code or etc. for clear understanding of your issue ? – Batuhan Aug 18 '21 at 23:16
  • No code needed @Batuhan . Just executing the command a that's it – Luis Frediani Aug 19 '21 at 00:37
  • https://stackoverflow.com/questions/45796776/get-connectionstring-from-appsettings-json-instead-of-being-hardcoded-in-net-co/58210975 – FarHard112 Aug 19 '21 at 01:39
  • Here is a solution to question deleted today : var results = context.Enrollments.GroupBy(x => x.CourseId).Where(x => !x.Any(x => x.StudentId == 1)).Select(x => x.Key).ToList(); – jdweng Sep 25 '22 at 13:43

1 Answers1

1

It becomes much easier if your console application uses generic host. The minimal code to scaffold is given as follows.

public class Program
{
    public static async Task  Main()
    {
        var builder = Host.CreateDefaultBuilder();

        builder.ConfigureHostConfiguration(icb =>
        {
            icb.AddUserSecrets<Program>();
        });

        await builder.Build().RunAsync();
    }
}

Your secret.json contains the connection string, for example:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.;Database=EFCoreConsoleDb;Integrated Security=true;TrustServerCertificate=true"
  }
}

Assuming your project name is EFCoreConsole and the active directory is the solution directory, execute the following batch to scaffold.

REM A batch file to scaffold!

dotnet ef dbcontext scaffold ^
name=DefaultConnection ^
Microsoft.EntityFrameworkcore.SqlServer ^
-s EFCoreConsole ^
--force ^
--context AppDbContext ^
--context-dir "Contexts" ^
--context-namespace EFCoreConsole.Contexts ^
--output-dir "Entities" ^
--namespace EFCoreConsole.Entities ^
--no-onconfiguring

Bonus

If you want to use the generated context and entities in the same project, here is the code.

public class Application : IHostedService
{
    private readonly AppDbContext context;

    public Application(AppDbContext context)
    {
        this.context = context;
    }
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        foreach (var p in await context.Products.ToArrayAsync())
            Console.WriteLine($"{p.Id}, {p.Description}");
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}


public class Program
{
    public static async Task  Main()
    {
        var builder = Host.CreateDefaultBuilder();

        builder.ConfigureHostConfiguration(icb =>
        {
            icb.AddUserSecrets<Program>();
        });

        builder.ConfigureServices((hbc, isc) =>
        {
            isc.AddDbContext<AppDbContext>(dcob =>
            {
                var constr = hbc.Configuration.GetConnectionString("DefaultConnection");
                //var constr = "DefaultConnection";
                dcob.UseSqlServer(constr);
            }, ServiceLifetime.Singleton);

            isc.AddHostedService<Application>();
        });   

       
        await builder.Build().RunAsync();
    }
}

Hopefully it is useful for the next generations.