Search code examples
c#entity-frameworkconsole-application.net-8.0

Console App - A named connection string was used, but the name 'DefaultConnection' was not found in the application's configuration


I have an issue where I am getting the following error when running my console app.

A named connection string was used, but the name 'DefaultConnection' was not found in the application's configuration

This is my program.cs

static async Task Main(string[] args)
{
    var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .Build();

    var sss = configuration.GetConnectionString("DefaultConnection");
    Console.WriteLine(sss);
    var serviceProvider = new ServiceCollection()
        .AddLogging(configure => configure.AddSerilog())
        .AddDbContext<MydbContext>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient)
        .AddScoped<IDataService, DataService>()
        .AddScoped<IMemoryCache, MemoryCache>()
        .AddScoped<IStockDataImportService, StockDataImportService>()
        .BuildServiceProvider();

    IStockDataImportService importService = serviceProvider.GetRequiredService<IStockDataImportService>();


    Console.WriteLine("Stock Data Import process started!");
    await FetchFile(logger, importService, configuration);
}

Now if I look at var sss. It contains the correct connection string so I know it is loading it from config correctly.

However I think it may be something to do with the GetRequiredService() line...

Either way my DataService class does not get the dbcontext correctly. It is a constructor parameter in the StockDataImporter class

public StockDataImportService(IDataService serv)
{
    _serv = serv;
}

and the dataservice class

public DataService(MydbContext context, IMemoryCache memoryCache) 
{
    _context = context;
    string? ddd = _context.Database.GetConnectionString();
    _memoryCache = memoryCache;
}

What am I doing wrong?


Solution

  • To fix your problem either remove the OnConfiguring(DbContextOptionsBuilder optionsBuilder) override or change it to something like:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer("name=DefaultConnection");
        }
    }
    

    so why is it the case that it works in blazor with the onconfigure but not the console app?

    I would guess that it works because it seems that you have IConfiguration registered in your Blazor app DI container. If you take a look at the code for NamedConnectionStringResolverBase which as far as I can see is internally invoked when processing the connection string then you will see that it will try to resolve and use the IConfiguration:

    // HERE:
    var configuration = ApplicationServiceProvider
        ?.GetService<IConfiguration>();
    
    var resolved = configuration?[connectionName]
                   ?? configuration?[DefaultSection + connectionName];
    
    if (resolved == null)
    {
        throw new InvalidOperationException(
            RelationalStrings.NamedConnectionStringNotFound(connectionName));
    }
    

    Of course you can try "fixing" your console app by registering the configuration in the container but still it is not the best option compared to the one suggested.