为什么我不能用=运算符设置DbContextOptions?

时间:2018-02-05 08:59:35

标签: c# entity-framework-core

为什么我不能使用以下

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)
....

3 个答案:

答案 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);
    }
}