Reputation: 15111
Why cannot I use the following
IServiceCollection service= new ServiceCollection();
var opt = new DbContextOptionsBuilder<Application>().UseSqlite("Data Source=MyDatabase.db");
service.AddDbContextPool<ApplicationContext>(options => options = opt);
instead of the following ?
IServiceCollection service= new ServiceCollection();
service.AddDbContextPool<ApplicationContext>(options => options.UseSqlite("Data Source=MyDatabase.db"));
Error message:
System.InvalidOperationException
HResult=0x80131509
Message=No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.GetRelationalService[TService](IInfrastructure`1 databaseFacade)
at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade)
....
Upvotes: 1
Views: 856
Reputation: 15111
The following code roughly simulates what the accepted answer means.
using System;
class DbContextOptionBuilder
{
public string ConnectionString { get; set; }
public override string ToString() => $"ConnectionString: {ConnectionString}";
}
class ServiceCollection
{
public void AddDbContext(Action<DbContextOptionBuilder> job)
{
DbContextOptionBuilder o = new DbContextOptionBuilder { ConnectionString = "Empty" };
job?.Invoke(o);
Console.WriteLine(o);
}
}
class Program
{
static void Wrong(DbContextOptionBuilder o)
{
o = new DbContextOptionBuilder { ConnectionString = "SQLITE" };
}
static void Correct(DbContextOptionBuilder o)
{
o.ConnectionString = "SQLITE";
}
static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
services.AddDbContext(Wrong);
services.AddDbContext(Correct);
}
}
Upvotes: 0
Reputation: 3367
It's because AddDbContextPool accepts an Action as parameter. This action in turn accepts an object of type DbContextOptionsBuilder. This action will be called by framework at some point and the framework will pass to this action an instance of the Builder that it created with some internal rules and tricks. You are supposed to further work with this object, not redefine it.
If you do the assignement you effectively overwrite the object created by framework with your own, which the framework knows nothing about. So all the internal logic of object creation, internal plumbing etc. is lost.
Upvotes: 1
Reputation: 157048
Here, (options => options = opt)
just works like a regular method:
private void Method(TypeOfParameter options)
{
options = opt;
}
Here, the options
variable is just overwritten. Nothing happens outside of the method. The variable that was used to call the method is not changed. That is why the assignment is useless and has no effect whatsoever.
Upvotes: 2