获得'语境不是可构建的。添加默认构造函数或提供IDbContextFactory的实现。“

时间:2013-04-12 05:27:41

标签: asp.net-mvc-4 ef-code-first ninject entity-framework-5 ef-migrations

当我尝试使用代码优先迁移时,我收到此错误。

我的上下文有一个带有连接名称的构造函数。

public class VeraContext : DbContext, IDbContext
{
    public VeraContext(string NameOrConnectionStringName = "VeraDB")
        : base(NameOrConnectionStringName)
    {
    }

    public IDbSet<User> Users { get; set; }
    public IDbSet<Product> Products { get; set; }
    public IDbSet<IntCat> IntCats { get; set; }
}

当项目运行时,这个连接名称是用ninject注入的,我也将它指定为默认值,如上面的代码所示,但这没有帮助。

kernel.Bind<IDbContext>()
    .To<VeraContext>()
    .WithConstructorArgument("NameOrConnectionStringName", "VeraDB");

当我尝试使用“启用 - 迁移”添加迁移时,会引发错误:

  

目标上下文'VeraData.EF.Infrastructure.VeraContext'不是   构造的。添加默认构造函数或提供实现   IDbContextFactory。

如果我从VeraContext删除构造函数,它将起作用,但会创建另一个名为VeraData.EF.Infrastructure.VeraContext的数据库。

我认为ninject仅在项目运行时传递连接字符串,而不是在我使用代码优先迁移时传递。无论如何,我可以在使用代码首次迁移时注入/提供连接名称的默认值?

4 个答案:

答案 0 :(得分:18)

基本上你需要一个默认的ctor(这是错误的) - 但只是实现它会导致问题。

您必须实现IDbContextFactory才能使结果保持一致(或者您从代码迁移不起作用等)。

  

迁移实际上会调用默认构造函数来创建   连接。所以你是其他ctor并不重要。

这是基本的工厂......

public class MyContextFactory : IDbContextFactory<MyContext>
{
    public MyContext Create()
    {
        return new MyDBContext("YourConnectionName");
    }
}

你应该将它与注入结合起来,根据需要注入和构建你的DbContext。

答案 1 :(得分:7)

如果您不想花时间查看IDbContextFactory选项,并且为了让事情正常工作,请在调用基本DbContext时创建默认构造函数并硬编码连接字符串的名称:

public class CustomContext : DbContext
{
    public CustomContext() :base("name=Entities") {} 
}

SRC:http://www.appetere.com/Blogs/SteveM/April-2012/Entity-Framework-Code-First-Migrations

答案 2 :(得分:1)

为了补充@ nccsbim071的答案,我还要补充一点......这个选项不喜欢带默认参数的构造函数...例如:

public MyContext(bool paramABC = false) : base("name=Entities") {...}

相反,您必须创建一个非参数(默认)构造函数和参数构造函数,如旧时尚方式。

public MyContext() :base("name=Entities") {...} 
public MyContext(bool paramABC) : this() {...}

注意:

    在这种情况下,
  • Entities表示连接字符串名称...按照惯例,上下文的名称与连接字符串名称相同,因为MyContext与{{1}不同必须手动指定它。

答案 3 :(得分:0)

在我的情况下,我想使用默认的连接工厂,而不是显式提供工厂。它将在EF6内的某个地方尝试查找工厂,但是由于出现此异常消息而失败。逐步执行EF6代码,我发现Glimpse.Ado正在包装连接工厂,这使the lookup找不到匹配项。