2

I have a .netcore 3.1 blazor app with EF Core 5 and after scaffolding my database with Scaffold-DbContext "Name=MyDb" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

Everything works without issue if I use Scaffold-DbContext "Server=servername;Database=MyDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force But I want to avoid having the connection string in the source code.

everything scaffolds correctly, however, when I try to display data to a list, a get this error: System.InvalidOperationException: A named connection string was used, but the name 'MyDb' 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.

Below is the code for my appsettings.json:

{
"ConnectionStrings": {
    "MyDb": "Server=servername;Database=MyDb;Integrated Security=True"
  }
}

Here is my MyDb_Context:

    public partial class MyDb_Context : DbContext
    {
        public MyDb_Context()
        {
        }

        public MyDb_Context(DbContextOptions<MyDb_Context> options)
            : base(options)
        {
        }

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

Here is my Startup.cs:

    public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            _env = env;
        }

        private readonly IWebHostEnvironment _env;
        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            var connection = Configuration.GetConnectionString("MyDb");
            services.AddDbContext<MyDb_Context>(options => options.UseSqlServer(connection));
        }
...
}

And here is what is being called in my service:

 public class MyDbService
    {
        public readonly MyDb_Context mydb_context;

        public MyDbService(MyDb_Context mydbctx)
        {
            MyDb_Context = mydbctx;
            MyDb_Context.Database.SetCommandTimeout(60);
        }

        public Task<List<MyDbTableName>> GetMyDbContent()
        {
            var usernames = mydb_context.usernames.Where(u => u.AppId == 2).ToListAsync();

            return usernames ;
        }
...
}

Then in my Razor page I am using the following code:

@code{
       private List<usernames> _usernames;

       
       MyDbService mydbservice = new MyDbService(new MyDb_Context()); //I think this line is where it is breaking

       protected override async Task OnInitializedAsync()
        {
            //Grab function from the service listed above
            //Function:
            _usernames = await mydbservice.GetMyDbContent();
        }

}

I have no idea why its not finding the connectionstring, and I can even put a breakpoint on startup.cs on optionsBuilder.UseSqlServer("Name=MyDb"); and it is able to read the connection string perfectly fine.

I also can see that DBContext gets loaded in when try services.toList(); and breakpoint on it.

Please help, I have been at this for over a week and have exhausted my efforts.

3
  • Register the service MyDbService in Startup services. Can you show code of using MyDbService. Commented Jan 21, 2021 at 22:33
  • Can you show where is the DbContext registered in the container? Commented Jan 22, 2021 at 8:11
  • 1
    I should note, that when using "Server=servername;Database=MyDb;Trusted_Connection=True;" hard coded connection string in MyDb_Context.cs, everything works without issue. I want to use the '"Name=MyDb" instead to avoid having the connection string in the source code. I've updated my question to include this info, my apologies Commented Jan 22, 2021 at 14:39

3 Answers 3

2
  • Register the service MyDbService in the Startup class to be injected latter by DI:
public void ConfigureServices(IServiceCollection services)
        {
            //...other services            
            services.AddScoped<MyDbService>();
        }
  • Inject the service into the component
@* inject the service *@
@inject MyDbService mydbservice
 
//....

@code{
    private List<usernames> _usernames;

//DO NOT instianate the service, it's injected 
   // MyDbService mydbservice = new MyDbService(new MyDb_Context()); //I think this line is where it is breaking

    protected override async Task OnInitializedAsync()
    {
        //Grab function from the service listed above
        //Function:
        _usernames = await mydbservice.GetMyDbContent(); //now it's working
    }
}

  • Modify the next line in the Constructor of MyDbService:
  // MyDb_Context = mydbctx; //invalid
  mydb_context = mydbctx;

The Scaffold-DbContext using named connection is valid because we are using DI.

Scaffold-DbContext "Name=MyDb" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

I tested this solution and it's working fine.

Sign up to request clarification or add additional context in comments.

1 Comment

Works! yes thank you! I should have known it wouldn't find the context because its initiating a new one. Do you happen to know if there is any documentation on this? I couldn't find anything involving razer components.
0

I doubt the Scaffold-DbContext Command has problem. I think you should give the complete connection string, something like this:

Scaffold-DbContext "Server=servername;Database=MyDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

1 Comment

By using Name=MyDb, I can avoid having connection strings in the source code, which is what I'd like to achieve.
0

In your MyDb_Context page, I didn't see puplic dbset<MyModel> Object {get; set;} , you need it to query and save an instance of your model!

1 Comment

Hi I have Public DbSet for each table in my context file, I have removed the content for the sake of this public question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.