エンティティタイプ<type>は現在のコンテキストのモデルの一部ではありません


146

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

}

このエラーが発生する具体的な理由はありますか?私は何の助けもなく、移行を有効にして自動移行を有効にしてみました。

回答:


142

これをカスタムDbContextクラスに配置します。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Estate>().ToTable("Estate");
}

起動時にテーブルが作成されない場合は、これが理由です。OnModelCreatingメソッドのオーバーライドで、それらについてDbContextに通知する必要があります。

ここでは、エンティティごとのカスタムマッピングを行うか、それらを個別のEntityTypeConfiguration<T>クラスに分離できます。


1
おかげで、ダン-これはそれを修正します。これでテーブルが作成されました。他に方法はありません、EFは自分でこれを行うことができませんか?エンティティに[ToTable( 'Estates')]などの注釈を付けることはできませんか?
janhartmann 2013

3
OnModelCreatingエンティティがと同じアセンブリにある場合は、オーバーライドしなくても機能する可能性がありますDbContext。ただし、エンティティにデータアノテーションを使用したことがないので、はっきりとは言えません。のアセンブリを常にスキャンしてOnModelCreating、他のアセンブリのエンティティを検索し、それらを自動的に登録することができます(これはTripodが行うことです)。
danludwig

ああ、もちろん。三脚の方法についてのメモをありがとう、私は今同様のことをしました、そしてそれはうまくいくようです。(github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/…のリフレクション拡張機能にも感謝します)。GetType()アセンブリを探す代わりに、参照アセンブリを見つけるだけです。"var assembly = Assembly.Load(" Dimension.Web.Domain ");" きれいではない;-)
janhartmann 2013

または、新しい/ Mapping /フォルダーをドメインではなく、Implプロジェクトに移動するだけかもしれません。
janhartmann 2013

@meepまたはdanludwig。三脚についてもっと教えてもらえますか、リンクを教えてください。
DkAngelito 14

73

どうやら、このエラーは非常に一般的で、いくつかの理由が考えられます。私の場合、それは次のとおりでした:によって生成された(Web.config内の)接続文字列.edmxが無効でした。ほぼすべてを試してから1日後、接続文字列を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= 
                               &quot;data source=(localdb)\v11.0; 
                               initial catalog=Blogging;
                               integrated security=True; 
                               multipleactiveresultsets=True;&quot;" 
     providerName="System.Data.EntityClient" /> 
</connectionStrings>

そして、ADO.NET文字列は次のようになります。

<connectionStrings>
  <add name="BlogContext"  
        providerName="System.Data.SqlClient"  
        connectionString="Server=.\SQLEXPRESS;Database=Blogging;
        Integrated Security=True;"/> 
</connectionStrings>

ソース:http : //msdn.microsoft.com/nl-nl/data/jj556606.aspx


17
私の問題は接続文字列にもありました。データモデルの名前を変更してt4テンプレートを再実行しましたが、接続文字列のメタデータ(.csdl、.ssdl、.mslファイル)を更新するのを忘れていました。あなたの答えは私がこれを理解するのに役立ったので、ありがとう!
Vyskol 2014年

4
認証にIdentityモデルを使用する場合、2つの接続文字列が必要です。1つは、名前を変更するかどうかにかかわらず、パブリックApplicationDbContext()に配置できる「DefaultConnection」です:base( "IdentityDbContext"、throwIfV1Schema:false){}これがエラーの原因ですあなたのように(そこにEF文字列がありました)2番目の接続文字列は、ウィザードを使用してEFを追加して作成されたもので、接続文字列パラメーターを要求します。これが誰かの役に立つことを願っています。
JustJohn 2015年

こっちも一緒。信じられないほどイライラする
Nick Molyneux 2016

1
からにアップグレードEF 4.xEF 6ます。テーブルを追加するには、接続文字列を再生成する必要がありました(DatabaseFirst)。私は私の中れたconnectionStringことに気づかなかったapp.configweb.config異なっていました。connectionstringから引き継ぐと、app.config動作し始めました。
DHFW

16

私にとっての問題は、エンティティフレームワークのコンテキスト内のdbセットにエンティティクラスが含まれていないことでした。

public DbSet<ModelName> ModelName { get; set; }

12

モデルからテーブルを削除して、もう一度追加してみてください。これは、ソリューションエクスプローラーから.edmxファイルを開いて視覚的に行うことができます。

手順:

  1. ソリューションエクスプローラーから.edmxファイルをダブルクリックします。
  2. 削除するテーブルヘッドを右クリックして、[モデルから削除]を選択します
  3. 作業領域をもう一度右クリックして、[データベースからモデルを更新]を選択します。
  4. テーブルリストからテーブルを再度追加します
  5. ソリューションをクリーンアップして構築する

8
最初にEFコードに.edmxがありません。
Tuukka Haapaniemi 16

ただし、+ 1を与えたのは、彼(またはこの問題を抱えている他の人)がコードファーストを
再考し

9

問題は接続文字列にある可能性があります。接続文字列がSqlClientプロバイダー用であり、EntityFrameworkに関連するメタデータが含まれていないことを確認します。


これはおそらく多くの人にとって明白でしたが、これは私の問題でした(db-firstとcode-firstの混合に関して)。これで、ホイールの回転を停止できます。ありがとうございました。
Bonez024

3

このエラーは、データベース内の既存のテーブルがコードファーストモデルに適切にマップされていない場合に発生しました。具体的には、データベーステーブルにchar(1)があり、C#にcharがありました。モデルを文字列に変更すると、問題が解決しました。


3

接続文字列のメタデータ部分を更新することで問題は解決しました。どうやらそれは間違った.csdl / .ssdl / .msl参照を指していた。


これも私に起こりました。他の場所からEF接続文字列をコピーし、メタデータのモデル名を更新していませんでした。
devC、

2

接続文字列で確認するもう1つのこと-モデル名。私は2つのエンティティモデルを使用していました。DBが最初です。構成で、エンティティ接続を1つコピーし、名前を変更して、接続文字列部分を変更しました。私が変更しなかったのはモデル名だったので、エンティティモデルは正しく生成されましたが、コンテキストが開始されたとき、EFはエンティティの間違ったモデルを探していました。

明らかなように書かれているように見えますが、私は戻ってこない4時間があります。


2

私にとっての問題は、モデルconnection stringによって生成されたADO.Net(.edmx)を使用することでした。接続文字列を変更すると問題が解決しました。


1

これは、何らかの理由で古くなった永続モデルキャッシュを使用している場合にも発生する可能性があります。コンテキストが(DbConfiguration.SetModelStoreを介して)ファイルシステムのEDMXファイルにキャッシュされている場合、キャッシュされたバージョンが使用されるため、OnModelCreatingが呼び出されることはありません。その結果、キャッシュされたストアにエンティティがない場合、接続文字列が正しく、テーブルがデータベースに存在し、エンティティがDbContextに正しく設定されていても、上記のエラーが発生します。


1

メッセージはかなり明確でしたが、最初はわかりませんでした...

2つのEntity Framework DBコンテキストsysContextshardContext同じメソッドで作業しています。

私が変更または更新したエンティティは、1つのコンテキストからのものですが、次のように他のコンテキストに保存しようとしました。

invite.uid = user.uid;

sysContext.Entry(invite).State = EntityState.Modified;

sysContext.SaveChanges(); // Got the exception here

しかし、正しいバージョンはこれでなければなりません:

invite.uid = user.uid;

shardContext.Entry(invite).State = EntityState.Modified;

shardContext.SaveChanges();

エンティティを正しいコンテキストに渡した後、このエラーはなくなりました。


0

明白に聞こえますが、タイプを明示的に無視していないことを確認してください。

modelBuilder.Ignore<MyType>();


0

構成に追加されたエンティティのマップ(空のものでも)は、エンティティタイプをコンテキストの一部にすることになります。空のマップで修正された、他のエンティティとの関係がないエンティティがありました。


0

最初にDBを試す場合は、テーブルに主キーがあることを確認してください


0

Visual Studio 2019がこれを引き起こしているようです。2017年にもう一度edmxモデルを生成して修正しました。


0

Entity Framewrokで同じ問題が発生し、以下の手順で解決しました:

1-Model.edmxを開く2-テーブルの場所を変更する(CSファイルを変更するため)3-それを保存する

私はあなたを助けたいと思います


0

.edmxファイルを削除して、再度追加します。特に、Entity Frameworkをアップグレードした場合。


0

EntityFrameworkCoreが値の範囲を更新しようとして同じ問題に直面していました。

このアプローチは機能しませんでした

  _dbSet.AttachRange(entity);
  _context.Entry(entity).State = EntityState.Modified;
   await _context.SaveChangesAsync().ConfigureAwait(false);

UpdateRangeメソッドを追加し、接続とエントリを削除した後、すべてが機能します

  _dbSet.UpdateRange(entity);
  await _context.SaveChangesAsync().ConfigureAwait(false);

0

私にとっては、エンティティクラスの名前を変更したことが原因でした。ロールバックしたときは、問題ありませんでした。


0

ばかげている可能性がありますが、いくつかのテーブルでのみこのエラーが発生した場合は、プロジェクトをクリーンアップして再構築することを忘れないでください(多くの時間を節約できる可能性があります)


0

私はこれを持っていた

using (var context = new ATImporterContext(DBConnection))
{
    if (GetID(entity).Equals(0))
    {
        context.Set<T>().Add(entity);
    }
    else
    {
        int val = GetID(entity);
        var entry = GetEntryAsync(context, GetID(entity)).ConfigureAwait(false);
        context.Entry(entry).CurrentValues.SetValues(entity);

    }
    
    await context.SaveChangesAsync().ConfigureAwait(false);
}

これは非同期メソッドにありましたが、GetEntryAsyncの前に待機するのを忘れたため、同じエラーが発生しました...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.