11

私はコード最初のマイグレーションを使用しようとすると、私はこのエラーを取得しています。'コンテキストを取得できません。デフォルトコンストラクタを追加するか、IDbContextFactoryの実装を提供します。」

私のコンテキストは、接続名を持つコンストラクタを持っている。

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

この私は「有効-MIとの移行を追加しようとすると、接続名は、プロジェクトの実行時に、私はまた、上記のコードでは、デフォルトとして、それを指定しているが、これは助けにはならなかった。

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

ninjectを注射します私はVeraContextからコンストラクタを削除した場合、それは動作します

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

が、その名前としてVeraData.EF.Infrastructure.VeraContextで別のデータベースを作成します。grations」されると、エラーをスローします。

ninjectは、プロジェクトの実行時に接続文字列を渡すだけで、コードの最初の移行は使用しないと仮定します。とにかく、最初の移行コードを使用するときに、接続名のデフォルトを注入/提供できますか?

+1

誰かがどこかで 'Kernel.Get'を実行しているときに、すべての問題が発生します。あなたはデフォルトのctorを追加するか、誰かがNinject経由でオブジェクトを構築するためにどのように移行のものをフックするかを伝えるのを待つ必要があります(あなたがやっていることですね!)。 –

+0

結果が一貫するようにするには 'IDbContextFactory'を実装する必要があります(または、コードからの移行が機能しないなど)。基本的には、デフォルトのctor(エラーです)が必要ですが、実装するだけで問題につながります。 – NSGaga

+0

'IDbContextFactory'は注入に適していません。単に設計通りに動作しません。まだそれのポイントを見ることができません... – nicodemus13

答えて

16

基本的にデフォルトのctorが必要です(エラーです)が、実装するだけで問題が発生します。

結果が一貫するようにするには、IDbContextFactoryを実装する必要があります(コードからの移行などは機能しません)。ここで

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

は、あなたが望むようにあなたのDbContextを注入し、構築するために、注射でそれを組み合わせなければならない基本的な工場...

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

です。

+0

'Create()'はパラメータを取らず、常にデフォルトのコンストラクタがなければならないので、さらに何を意味するのか説明できますか? - それで、どこにも注射する必要はありません。少なくともコンストラクタインジェクションはありません。 – nicodemus13

+0

@ nicodemus13それはずっと前のことでしたが、覚えているとおり、一貫したDbContext構築を保証することです。 EFは、自動化によってデフォルトの呼び出し元を呼び出します。必要であれ、そうでなくても、必要な場合はカスタム呼び出し元が呼び出されません。工場は主にEF呼び出しのためのもので、DbContextの注入を正常に使用できます。しかし、b)ほとんどのIoCコンテナを思い出す限り(私は多くのものを使用しない)、例えば、コンテナ。を作成し、工場に従事する匿名のメソッドをいくつか作成します(工場がもっと複​​雑なので、そうしなければ、私が言ったのと同じです)。 – NSGaga

+1

@NSGaga - DbContextまたは接続文字列を挿入できない理由コンストラクタを介してMyContextFactoryに渡してから、createメソッドで新しいDbContextをnewする代わりにDbContextを返します。 –

6

あなたは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

1

がnccsbim071答え@補完するために、私は1つのより多くの事を追加する必要があります...このオプションは、たとえば...デフォルトパラメータを持つコンストラクタを好きではない:

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

代わりに、パラメータのない(デフォルトの)コンストラクタと古いファッションウェイのようなパラメータコンストラクタを作成する必要があります。

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

注:このケースで

  • Entitiesが慣例で...接続文字列の名前を意味し、コンテキストの名前は、接続文字列の名前と同じであるとMyContextので、同じではありませんEntitiesとして、手動で指定する必要があります。
関連する問題