Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting 'Context is not constructible. Add a default constructor or provide an implementation of IDbContextFactory."

I am getting this error when I try to use code first migrations.

My context has a constructor with the connection name.

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; }
}

This connection name is injected with ninject when the project runs, I have also specified it as a default as in the above code but this did not help.

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

When I try to add migrations with "Enable-Migrations" is throws up the error:

The target context 'VeraData.EF.Infrastructure.VeraContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.

If I remove the constructor from VeraContext it will work but creates another database with VeraData.EF.Infrastructure.VeraContext as its name.

I presume that ninject only passes the connection string when the project runs and not when I use code first migrations. Anyway I can inject/provide a default for the connection name when using code first migrations ?

like image 568
LaserBeak Avatar asked Apr 12 '13 05:04

LaserBeak


3 Answers

Essentially you need a default ctor (that's the error) - but just implementing it would lead to problems.

You'd have to implement the IDbContextFactory for the results to be consistent (or your migration from code won't work etc.).

Migrations actually call your default constructor to make a connection. So you're other ctor won't matter much.

Here is the basic factory...

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

You should combine that with injection, to inject and construct your DbContext as you wish.

like image 152
NSGaga-mostly-inactive Avatar answered Sep 18 '22 12:09

NSGaga-mostly-inactive


If you don't want to spend time looking into the IDbContextFactory option, and to get things working create a default constructor and hard-code the name of the connection string when calling the base DbContext:

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

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

like image 20
NCCSBIM071 Avatar answered Sep 18 '22 12:09

NCCSBIM071


To complement @nccsbim071 answer, I have to add one more thing... this option doesn't like constructor with default parameters... for instance:

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

instead you have to create a non-parameter (default) constructor and the parameter-constructor like old fashion way.

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

NOTE:

  • Entities in this case means the connection string name... By convention, the name of the context is the same as the connection string name and since MyContext is not the same as Entities, it's necessary specify it manually.
like image 25
Jaider Avatar answered Sep 18 '22 12:09

Jaider