2017-03-25 63 views
0

我不确定我在做什么错误,我想使用来自appsettings.json的连接字符串并使用DI来设置我的DbContext以供使用。ASP.NET Core中的连接字符串DI

{ 
    "ConnectionStrings": { 
    "DarkwinterDatabase": "server=localhost;userid=user;pwd=pass;port=3306;database=Darkwinter;sslmode=none;" 
    }, 
    ... 
} 

在Startup.cs的ConfigureServices方法中,我有以下代码。

services.AddDbContext<PostContext>(options => 
    options.UseMySQL(Configuration.GetConnectionString("DarkwinterDatabase"))); 

我的DbContext具有一个DbSet并接受DbContextOptions传递给基座被初始化。这是我认为我错了的地方,但是如果DI将选项传递给此类?

public class PostContext : DbContext 
{ 
    public PostContext(DbContextOptions options) : base(options) { } 
    public DbSet<Post> Post { get; set; } 
} 

如何过,当我尝试使用我的背景,我得到一个错误:没有给定参数对应于PostContext.PostContext的”所需的形式参数“选项”(DbContextOptions)

using(var db = new PostContext()) 
{ 
    var posts = db.Post.ToList(); 
    return View(posts); 
} 

这是有道理的,因为我没有通过,但我认为服务应该这样做?我知道我正在考虑这个错误的方式,并希望有人会花时间向我解释。

+0

什么是DI发动机你使用?你在哪里配置DI来了解'DbContextOptions'类型的对象? – Emad

回答

2

您正在考虑正确的方法。但是,有几个问题。

让我解释一下:根据Dependency Injection documentationAddDbContext是.NET核心依赖注入的注册扩展方法,这是正确的。

更重要的是了解你在注射什么。这实际上很简单:通过AddDbContext<PostContext>,您告诉DI框架“注入PostContext作为应用程序Db上下文,在任何需要它的地方”。

现在,让我们检查的内容有PostContext(这就是你想要的东西注入到):

public PostContext(DbContextOptions options) 

您尝试使用构造器注入,这是一个很好的开始。您也期待注入DbContextOptions。然而,DI框架不知道要为DbContextOptions注入什么 - 您只告诉它关于ApplicationDbContext,它不知道注入哪个注入(,您可能注册了不同上下文的bazillion)。

您可以将其更改为ApplicationDbContext(否则一切都写在下面,使零意义):

AddDbContext<ApplicationDbContext>(//...) 

现在,你原来的DbContext服务定义做得好,但它仍然没有工作。对你来说有好消息:你不是唯一一个通过这种行为冲击的人:“我在注册一个ApplicationDbContext,然后要求DbContextOptions,我真的希望发生这种奇迹”(ref。 Entity Framework Issue #4558)。

我从来没有真正尝试过,但根据Entity Framework Issue #4668DbContextOptions<TContext>被添加到应用程序的服务提供商。现在,你可能已经猜到的伎俩尝试:让构造要求DbContextOptions<TContext>(如果您已经改变了注册即可使用ApplicationDbContext代替PostContext),像这样:

public class PostContext : DbContext 
{ 
    public PostContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } 
    public DbSet<Post> Post { get; set; } 
} 

还是喜欢这个,如果你已经决定留在AddDbContext<PostContext>

public class PostContext : DbContext 
{ 
    public PostContext(DbContextOptions<PostContext> options) : base(options) { } 
    public DbSet<Post> Post { get; set; } 
} 

同样,不知道这是否会工作,从来没有尝试过。如果它不 - 好,你就必须实现一个上下文选项工厂,转而注入它...

+0

不幸的是,这并不适合我,但你的回答非常有见地,我学到了很多东西。我仍在玩DI,尝试不同的东西,但同时我已经硬编码我的连串字符串以继续开发我的博客。再次感谢你的帮助。 –

0

你可以试试这个在您的startup.cs文件

services.AddDbContext<PostContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DarkwinterDatabase")));