私はEntity Frameworkに参加していますが、コードファーストアプローチの重要なポイントを見逃しているかどうかはわかりません。
私は https://genericunitofworkandrepositories.codeplex.com/ のコードに基づく一般的なリポジトリパターンを使用していて、私のエンティティを作成しました。
しかし、私がそのエンティティにアクセスしたり変更したりしようとすると、私は次のようになります。
System.InvalidOperationException:エンティティタイプEstateは、現在のコンテキストのモデルには含まれていません。
リポジトリからアクセスしようとしたときに発生します。
public virtual void Insert(TEntity entity)
{
((IObjectState)entity).ObjectState = ObjectState.Added;
_dbSet.Attach(entity); // <-- The error occurs here
_context.SyncObjectState(entity);
}
データベース(./SQLEXPRESS)は問題なく作成されますが、エンティティ(テーブル)は起動時には作成されません。
エンティティのマッピングを明示的に設定する必要があるかどうか疑問に思いますか。 EFはそれだけではこれができないのでしょうか。
私の存在は:
public class Estate : EntityBase
{
public int EstateId { get; set; }
public string Name { get; set; }
}
私の文脈はそうです:
public partial class DimensionWebDbContext : DbContextBase // DbContextBase inherits DbContext
{
public DimensionWebDbContext() :
base("DimensionWebContext")
{
Database.SetInitializer<DimensionWebDbContext>(new CreateDatabaseIfNotExists<DimensionWebDbContext>());
Configuration.ProxyCreationEnabled = false;
}
public new IDbSet<T> Set<T>() where T : class
{
return base.Set<T>();
}
}
このエラーが発生する特別な理由はありますか?私は移行を有効にして自動移行を有効にしようとしましたが、何の手助けもありません。
これをカスタムのDbContext
クラスに入れます。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Estate>().ToTable("Estate");
}
起動時にテーブルが作成されていないのであれば、これが理由です。 OnModelCreatingメソッドのオーバーライドでそれらについてDbContextに伝える必要があります。
ここでエンティティごとのカスタムマッピングを行うことも、別々のEntityTypeConfiguration<T>
クラスに分離することもできます。
どうやら、このエラーは非常に一般的です、それはいくつかの理由があるかもしれません。私の場合は、次のようになりました。.edmx
によって生成された接続文字列(Web.config内)が無効でした。ほとんどすべてのことを試してから、接続文字列をEF文字列からADO.NET文字列に変更しました。これで私の問題は解決しました。
たとえば、EF文字列は次のようになります。
<connectionStrings>
<add name="BlogContext"
connectionString="metadata=res://*/BloggingModel.csdl|
res://*/BloggingModel.ssdl|
res://*/BloggingModel.msl;
provider=System.Data.SqlClient
provider connection string=
"data source=(localdb)\v11.0;
initial catalog=Blogging;
integrated security=True;
multipleactiveresultsets=True;""
providerName="System.Data.EntityClient" />
</connectionStrings>
そしてADO.NET文字列は次のようになります。
<connectionStrings>
<add name="BlogContext"
providerName="System.Data.SqlClient"
connectionString="Server=.\SQLEXPRESS;Database=Blogging;
Integrated Security=True;"/>
</connectionStrings>
私にとっての問題は、エンティティフレームワークのコンテキスト内のデータベースセットにエンティティクラスが含まれていなかったことです。
public DbSet<ModelName> ModelName { get; set; }
問題は接続文字列にあります。接続文字列がSqlClientプロバイダ用で、EntityFrameworkに関連するメタデータがないことを確認してください。
モデルからテーブルを削除して再度追加してみてください。ソリューションエクスプローラーから.edmxファイルを開くことによってこれを視覚的に行うことができます。
ステップ:
データベース内の既存のテーブルがコード優先モデルに適切にマッピングされていないときにこのエラーが発生しました。具体的には、データベーステーブルにchar(1)、C#にcharがあります。モデルを文字列に変更して問題を解決しました。
私の問題は、接続文字列のメタデータ部分を更新することによって解決されました。どうやらそれは間違った.csdl/.ssdl/.msl参照を指していました。
私にとって問題は、connection string
Model(.edmx)によって生成されたADO.Net
を使用したことです。接続文字列を変更することで私の問題は解決しました。
接続文字列を確認するもう1つのこと - モデル名。私はDBを最初に、2つのエンティティモデルを使用していました。設定では、エンティティ接続を1つにコピーし、名前を変更して、接続文字列部分を変更しました。私が変更しなかったのはモデル名でした。そのためエンティティモデルは正しく生成されましたが、コンテキストが開始されたときはEFはエンティティに対して間違ったモデルを調べていました。
明らかに書き留めてあるように見えます、しかし、私が戻ることができない4時間があります。
これは、何らかの理由で古くなっている永続モデルキャッシュを使用している場合にも発生する可能性があります。コンテキストがファイルシステム上のEDMXファイルに(DbConfiguration.SetModelStoreを介して)キャッシュされている場合は、キャッシュされたバージョンが使用されるため、OnModelCreatingは呼び出されません。その結果、キャッシュされたストアにエンティティがない場合は、接続文字列が正しく、テーブルがデータベースに存在し、エンティティがDbContextに正しく設定されていても上記のエラーが発生します。
Visual Studio 2019はこれを引き起こしているようです。 2017年にedmxモデルを再度生成することで修正しました。
あなたが最初にDBを試しているのであれば、あなたのテーブルが持っていることを確認してください主キー
明らかに聞こえますが、型を明示的に無視していないことを確認してください。
modelBuilder.Ignore<MyType>();
構成に追加されたエンティティのマップ(空のものであっても)は、エンティティタイプをコンテキストの一部にすることになります。空のマップで修正された他のエンティティと関係のないエンティティがありました。