web-dev-qa-db-ja.com

'コンテキストの取得は構築できません。デフォルトのコンストラクターを追加するか、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; }
}

この接続名は、プロジェクトの実行時にninjectが挿入されます。また、上記のコードのようにデフォルトとして指定しましたが、これは役に立ちませんでした。

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

「Enable-Migrations」を使用して移行を追加しようとすると、エラーがスローされます。

ターゲットコンテキスト「VeraData.EF.Infrastructure.VeraContext」は構築できません。デフォルトのコンストラクターを追加するか、IDbContextFactoryの実装を提供します。

コンストラクターをVeraContextから削除すると機能しますが、名前としてVeraData.EF.Infrastructure.VeraContextを使用して別のデータベースが作成されます。

ninjectは、プロジェクトの実行時にのみ接続文字列を渡し、コードの最初の移行を使用するときは渡さないと思います。とにかく、コードファーストマイグレーションを使用するときに接続名のデフォルトを挿入/提供できますか?

14
LaserBeak

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

結果の一貫性を保つには、IDbContextFactoryを実装する必要があります(または、コードからの移行が機能しないなど)。

移行では、実際にはデフォルトのコンストラクターを呼び出して接続を確立します。だからあなたは他のctorはそれほど重要ではありません。

これが基本的な工場です...

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

これをインジェクションと組み合わせて、必要に応じてDbContextをインジェクトおよび構築する必要があります。

18
NSGaga

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

7
nccsbim071

@ nccsbim071の回答を補完するために、もう1つ追加する必要があります...このオプションは、デフォルトのパラメーターを持つコンストラクターを好みません...たとえば:

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

代わりに、非パラメーター(デフォルト)コンストラクターと、昔ながらの方法のようなパラメーターコンストラクターを作成する必要があります。

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

注意:

  • この場合のEntitiesは接続文字列名を意味します...慣例により、コンテキストの名前は接続文字列名と同じであり、MyContextEntities、手動で指定する必要があります。
1
Jaider