web-dev-qa-db-ja.com

足場コントローラーはVisual Studio 2013 Update 3および4で動作しません

Visual Studio 2013(更新3および4)でコントローラー(Entity Frameworkを使用したビューを備えたMVC5コントローラー)をスキャフォールドできません。エラーメッセージは次のとおりです。

選択したコードジェネレーターの実行中にエラーが発生しました:

A configuration for type 'Library.Morthwind.Models.Catgeory' has already been added. To reference the existing configuration use the Entity<T>() or ComplexType<T>() methods

「Entity Framework Power Tools Beta 4」ツールメニューから「Reverse Engineer Code First」を選択してモデルを作成しました。

このエラーの原因についてのアイデアはありますか?

42
SimonB

今日も同じ問題がありました。

Fluent APIを使用して関係を追加するために、モデルクラスの1つにカスタム構成をいくつか追加しました。これは、次を使用してdbContextオーバーライドのOnModelCreatingクラスで指定されました。

modelBuilder.Configurations.Add(new OrderConfiguration());

上記の行をコメントアウトすると、Controller scaffoldが期待どおりに実行できました。

VS 2013 update 2にはこれに関する問題があり、scaffoldingは、詳細な情報がなく、役に立たないエラーを出しました。インストールされたUpdate 3では、根本的な問題を追跡するのに十分な詳細が提供されました。

ジェフ。

40
Jeff

私もこの問題を抱えています。ジェフのソリューションは、場合によっては機能します。しかし、キーをマップする必要のあるモデルが増えてDbContextが大きくなると、EFが主キーを見つけられないなどのエラーが発生するため、Configurations.Add()メソッドを削除できませんでした。

DBContext派生クラスを変更して、DbSetの代わりにIDbSetプロパティを使用することで、コントローラーとビューをうまく生成できることを発見しました。ただし、私にとってこれは別の問題を引き起こし、IDbSetは非同期メソッドをサポートしません。

構成が設定された非非同期コントローラーまたは構成クラスのない非同期メソッドを生成できるようです。

コンテキストプロパティがDbSet型の場合は、IDbSetに変更してみてください。非同期コントローラーメソッドを生成していない場合は、これが有効な場合があります。

19
Brian Scott

また、同じ問題があり、IDbSetを使用するようにコンテキストクラスを変更すると、足場を正常に使用して新しいコントローラーを作成できました。しかし、非同期メソッドを放棄したくなかったため、コンテキストをDbSetを使用するように変更しました。

6
Gandyman

この問題の解決方法を次に示します。 Visual Studio 2013 Update 4を持っています。
EF Power Toolsを使用しています。すべてのDbSet <...> OnModelCreatingの内部で、足場となるオブジェクトのみを残します。modelBuilder.Configurations.Add(new SomeTableDataMap());

コンテキストクラスの下部で、これが作成されていることに気付きました。public System.Data.Entity.DbSet SomeTableDatas {get;セットする; }

ああ:私もこれをコンストラクタに入れましたが、これは何か他のもののためです。this.Configuration.LazyLoadingEnabled= false;

真剣に、これは今日は機能しましたが、Update 4では何も機能しないこれらのソリューションをすべて試しました。以前のソリューションを使用して、Update 2およびUpdate 3でこれを機能させました。これは今のところ最新のソリューションです。

3
Luke G

私のために働いた簡単な回避策(ここで提案された他の多くの解決策を試してみた後、無駄に他の場所...).

Scaffoldingダイアログで、新しいDataContextを追加しました。 TempContext。足場はすべて正常に機能し、TempContextで生成されたコードを元のDbContextに移動し、生成されたコントローラーのTempContextの名前を元のDbContextに変更するだけで済みました。

2
Richard Houltz

この問題については、すでに複数の回避策が投稿されています。そして、このコメントでは、なぜこれが失敗するのかという根本的な問題を提供しようとします。 [人々に根本原因を認識させたい]

アプリケーションにDbContext(具体的にはDbContextの子クラス)があり、モデルクラス(たとえばModel)とDbContextおよびscaffolding controller/viewsを使用しようとしているとします。

DbContextには「DbSet <Model> Models {get; set;}」プロパティがありませんが、それでもOnModelCreatingメソッドのコードを使用してDbSetがDbContextに追加されたと推測しています。

上記の場合、scaffoldingは最初にDbContextのDbSetプロパティを検出しようとします(リフレクションのみ-OnModelCreatingにDbSetを追加するコードがあるかどうかを検出しないため)、それがない場合、scaffoldingはDbContextにDbSetプロパティを追加してから、そのDbContextを使用するスキャフォールドですが、スキャフォールディングの実行時にDbContextのインスタンスを作成し、OnModelCreatingも呼び出します。その時点で、DbContextに同じモデルを持つ複数のDbSetタイプ(スキャフォールディングとOnModelCreatingのコードで構成されています)。

[これは、使用されているモデルだけでなく、そのモデルの関連モデルでも発生します。足場は、すべての関連モデルのDbSetプロパティを追加します]

[また、Jeffが述べたように、操作が正常に完了しなかった場合、scaffoldが変更をロールバックするため、足場が完了した後、追加されたDbSetが表示されません。しかし、まだ何が起こっているのかはあまり明確ではない]

これはscaffoldingのバグです。簡単な回避策は、OnModelCreatingで設定する代わりに、モデルクラスのすべての関連モデルに対してDbContextのDbSetプロパティを使用することです。

1
pradeep

この投稿の答えはどれも役に立たなかった。 [コントローラーの足場の追加]ダイアログのプラスボタンを使用して、新しいコンテキストクラスを作成するこの問題を処理しました。 VSがコントローラーとビューを作成したら、作成されたコンテキストクラスを削除し、既存のコンテキストクラスを使用するように生成されたコントローラーコードを変更します。

重要:このプロセスは、新しいコンテキストに新しい接続文字列を追加します。削除することも忘れないでください。

0
Luty

コンテキストクラス内のOnModelCreating関数にコードのtry/catchを追加することで解決しました。 base.OnModelCreating(modelBuilder);を保持するだけです。

あなたのtry/catchの外

0
Anas Ghanem

私のこのように修正されました:

    public virtual DbSet<Category> Categories { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //--> EntityTypeConfiguration<Your Model Configuration>
        modelBuilder.Configurations.Add(new EntityTypeConfiguration<CategoryMapping>());  

        base.OnModelCreating(modelBuilder);
    }

Ctrl + Shift + Bを忘れないでコードをコンパイルします(単一のソリューションについてはわかりませんが、同じソリューションの別のプロジェクトにあるので、最初にコンパイルする必要があります)

0
deadManN

残りの答えはどれも私にとってはうまくいきませんでした。私が見つけたのは、Fluent APIを使用して構成をスキャフォールディングおよび追加するときにのみ問題が発生するということです。だから私がやったことは、ファイルを分離する代わりに、それぞれが次のようなエンティティ設定を持っていることでした:

public class ApplicationUserMapConfiguration : EntityTypeConfiguration<ApplicationUserMap>
{
    public ApplicationUserMapConfiguration()
    {
        ToTable("ApplicationUserMap", "Users");
        HasKey(c => c.Id);
     }
}

そして、この構成をDbContextに追加します。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Configurations.Add(new ApplicationUserMapConfiguration()); 
}

すべてのエンティティのDbContext内に構成全体を追加しました。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //ApplicationUser

        modelBuilder.Entity<ApplicationUser>().HasKey(c => c.Id);
        modelBuilder.Entity<ApplicationUser>().ToTable("ApplicationUser", "Usuario");

        //Other entities...
    }

今、私は完璧に足場することができます。私はすでに提出して Mvc GitHub上 を発行しています。

また、次のような別のエラーメッセージが表示された場合:

選択したコードジェネレーターの実行中にエラーが発生しました:「呼び出しのターゲットによって例外がスローされました。」

DbContextコンストラクターを次のように変更する必要があります。

public YourDbContext() : base("YourDbContext", throwIfV1Schema: false) { }
0
Hernan Demczuk

CRUDアクションとビューを使用してコントローラーをスキャフォールドしようとすると、別のエラーが発生していました。私の場合、それは言っていました:

「選択したコードジェネレーターの実行中にエラーが発生しました。オブジェクトインスタンスがオブジェクトのインスタンスに設定されていません。」

問題を見つけるのは困難でした。SQL Serverにテーブルを作成しましたが、テーブルにPrimary Keyを設定するのを忘れていました。 Primary keyを設定し、Entity Frameworkの.edmxファイルを更新することで問題が解決しました。

それが役に立てば幸い。

0