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」を選択してモデルを作成しました。
このエラーの原因についてのアイデアはありますか?
今日も同じ問題がありました。
Fluent APIを使用して関係を追加するために、モデルクラスの1つにカスタム構成をいくつか追加しました。これは、次を使用してdbContext
オーバーライドのOnModelCreating
クラスで指定されました。
modelBuilder.Configurations.Add(new OrderConfiguration());
上記の行をコメントアウトすると、Controller
scaffoldが期待どおりに実行できました。
VS 2013 update 2にはこれに関する問題があり、scaffoldingは、詳細な情報がなく、役に立たないエラーを出しました。インストールされたUpdate 3では、根本的な問題を追跡するのに十分な詳細が提供されました。
ジェフ。
私もこの問題を抱えています。ジェフのソリューションは、場合によっては機能します。しかし、キーをマップする必要のあるモデルが増えてDbContextが大きくなると、EFが主キーを見つけられないなどのエラーが発生するため、Configurations.Add()メソッドを削除できませんでした。
DBContext派生クラスを変更して、DbSetの代わりにIDbSetプロパティを使用することで、コントローラーとビューをうまく生成できることを発見しました。ただし、私にとってこれは別の問題を引き起こし、IDbSetは非同期メソッドをサポートしません。
構成が設定された非非同期コントローラーまたは構成クラスのない非同期メソッドを生成できるようです。
コンテキストプロパティがDbSet型の場合は、IDbSetに変更してみてください。非同期コントローラーメソッドを生成していない場合は、これが有効な場合があります。
また、同じ問題があり、IDbSetを使用するようにコンテキストクラスを変更すると、足場を正常に使用して新しいコントローラーを作成できました。しかし、非同期メソッドを放棄したくなかったため、コンテキストをDbSetを使用するように変更しました。
この問題の解決方法を次に示します。 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でこれを機能させました。これは今のところ最新のソリューションです。
私のために働いた簡単な回避策(ここで提案された他の多くの解決策を試してみた後、無駄に他の場所...).
Scaffoldingダイアログで、新しいDataContextを追加しました。 TempContext。足場はすべて正常に機能し、TempContextで生成されたコードを元のDbContextに移動し、生成されたコントローラーのTempContextの名前を元のDbContextに変更するだけで済みました。
この問題については、すでに複数の回避策が投稿されています。そして、このコメントでは、なぜこれが失敗するのかという根本的な問題を提供しようとします。 [人々に根本原因を認識させたい]
アプリケーションに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プロパティを使用することです。
この投稿の答えはどれも役に立たなかった。 [コントローラーの足場の追加]ダイアログのプラスボタンを使用して、新しいコンテキストクラスを作成するこの問題を処理しました。 VSがコントローラーとビューを作成したら、作成されたコンテキストクラスを削除し、既存のコンテキストクラスを使用するように生成されたコントローラーコードを変更します。
重要:このプロセスは、新しいコンテキストに新しい接続文字列を追加します。削除することも忘れないでください。
コンテキストクラス内のOnModelCreating関数にコードのtry/catchを追加することで解決しました。 base.OnModelCreating(modelBuilder);を保持するだけです。
あなたのtry/catchの外
私のこのように修正されました:
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を忘れないでコードをコンパイルします(単一のソリューションについてはわかりませんが、同じソリューションの別のプロジェクトにあるので、最初にコンパイルする必要があります)
残りの答えはどれも私にとってはうまくいきませんでした。私が見つけたのは、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) { }
CRUDアクションとビューを使用してコントローラーをスキャフォールドしようとすると、別のエラーが発生していました。私の場合、それは言っていました:
「選択したコードジェネレーターの実行中にエラーが発生しました。オブジェクトインスタンスがオブジェクトのインスタンスに設定されていません。」
問題を見つけるのは困難でした。SQL Server
にテーブルを作成しましたが、テーブルにPrimary Key
を設定するのを忘れていました。 Primary key
を設定し、Entity Frameworkの.edmx
ファイルを更新することで問題が解決しました。
それが役に立てば幸い。