为什么我不能使用以下
IServiceCollection service= new ServiceCollection();
var opt = new DbContextOptionsBuilder<Application>().UseSqlite("Data Source=MyDatabase.db");
service.AddDbContextPool<ApplicationContext>(options => options = opt);
而不是以下?
IServiceCollection service= new ServiceCollection();
service.AddDbContextPool<ApplicationContext>(options => options.UseSqlite("Data Source=MyDatabase.db"));
错误讯息:
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)
....
答案 0 :(得分:2)
在这里,(options => options = opt)
就像常规方法一样:
private void Method(TypeOfParameter options)
{
options = opt;
}
这里,options
变量只是被覆盖了。在方法之外没有任何事情发生。用于调用方法的变量不会更改。这就是为什么作业没用,也没有任何效果。
答案 1 :(得分:1)
这是因为AddDbContextPool接受Action作为参数。此操作又接受DbContextOptionsBuilder类型的对象。框架会在某个时刻调用此操作,框架会将使用某些内部规则和技巧创建的Builder实例传递给此操作。你应该进一步使用这个对象,而不是重新定义它。
如果您进行了分配,则可以使用您自己的框架有效地覆盖框架创建的对象,框架对此一无所知。因此,对象创建,内部管道等的所有内部逻辑都将丢失。
答案 2 :(得分:0)
以下代码大致模拟了接受的答案意味着什么。
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);
}
}