Tipe entitas <type> bukan bagian dari model untuk konteks saat ini

147

Saya masuk ke Kerangka Entitas, tapi saya tidak yakin apakah saya kehilangan titik kritis dalam pendekatan kode-pertama.

Saya menggunakan pola repositori generik berdasarkan kode dari https://genericunitofworkandrepositories.codeplex.com/ dan telah membuat entitas saya.

Tetapi ketika saya mencoba mengakses atau memodifikasi entitas saya mengalami hal-hal berikut:

System.InvalidOperationException: Jenis entitas Estate bukan bagian dari model untuk konteks saat ini.

Itu terjadi ketika saya mencoba mengaksesnya dari repositori saya:

public virtual void Insert(TEntity entity)
{
    ((IObjectState)entity).ObjectState = ObjectState.Added;
    _dbSet.Attach(entity); // <-- The error occurs here
    _context.SyncObjectState(entity);
}

Basis data (./SQLEXPRESS) dibuat dengan baik, tetapi entitas (tabel) tidak dibuat saat startup.

Saya bertanya-tanya apakah saya perlu mengatur pemetaan entitas secara eksplisit? Apakah EF tidak dapat melakukan ini sendiri?

Entitas saya adalah:

public class Estate : EntityBase
{
    public int EstateId { get; set; }
    public string Name { get; set; }
} 

Konteks saya adalah seperti itu:

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

}

Apakah ada alasan khusus mengapa kesalahan ini terjadi? Saya telah mencoba mengaktifkan migrasi dan mengaktifkan migrasi otomatis tanpa bantuan apa pun.

janhartmann
sumber

Jawaban:

143

Masukkan ini ke DbContextkelas khusus Anda :

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

Jika tabel Anda tidak dibuat saat startup, inilah sebabnya. Anda perlu memberi tahu DbContext tentang mereka di override metode OnModelCreating.

Anda dapat melakukan pemetaan khusus per entitas di sini, atau memisahkannya ke dalam EntityTypeConfiguration<T>kelas terpisah .

danludwig
sumber
1
Terima kasih, Dan - ini memperbaikinya. Sekarang tabel dibuat. Tidak ada jalan lain, EF tidak dapat melakukan ini sendiri? Saya tidak bisa hanya membubuhi keterangan entitas dengan [ToTable ('Estates')] atau sesuatu seperti itu?
janhartmann
3
Saya pikir itu mungkin berhasil tanpa mengesampingkan OnModelCreatingjika entitas Anda berada di majelis yang sama dengan Anda DbContext. Saya belum pernah menggunakan anotasi data untuk entitas, jadi saya tidak bisa mengatakan dengan pasti. Anda selalu dapat memindai rakitan di Anda OnModelCreatinguntuk menemukan entitas di rakitan lain dan mendaftarkannya secara otomatis (seperti yang dilakukan Tripod).
danludwig
Ah, tentu saja. Terima kasih atas catatan tentang cara Tripod melakukannya, saya telah melakukan hal serupa sekarang, dan sepertinya berfungsi dengan baik. (juga berkat ekstensi refleksi Anda di: github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/… ). Sekarang saya hanya perlu menemukan rakitan referensi daripada melihat melalui perakitan GetType (). "var assembly = Assembly.Load (" Dimension.Web.Domain ");" tidak cantik ;-)
janhartmann
Atau mungkin hanya memindahkan folder / Pemetaan / baru saya ke proyek Impl saya alih-alih Domain saya.
janhartmann
@meep atau danludwig. Bisakah Anda ceritakan lebih lanjut tentang Tripod atau bagikan tautan kepada saya.
DkAngelito
73

Rupanya, kesalahan ini sangat umum, bisa jadi ada beberapa alasan. Dalam kasus saya, itu adalah sebagai berikut: String koneksi (di Web.config) yang dihasilkan oleh .edmxtidak valid. Setelah hampir satu hari mencoba semuanya, saya mengubah string koneksi dari string EF ke string ADO.NET. Ini menyelesaikan masalah saya.

Misalnya, string EF terlihat seperti ini:

<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>

Dan string ADO.NET terlihat seperti ini:

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

Sumber: http://msdn.microsoft.com/nl-nl/data/jj556606.aspx

Christiaan Maks
sumber
17
Masalah saya juga ada di string koneksi. Saya telah mengganti nama model data saya dan memutar ulang templat t4 saya, tetapi lupa memperbarui metadata (.csdl, .ssdl, file .msl) di string koneksi. Jawaban Anda membantu saya menyadari hal ini, jadi terima kasih!
Vyskol
4
Jika menggunakan model Identity untuk autentikasi, Anda memerlukan 2 koneksi string: satu, "DefaultConnection" yang dapat Anda rename atau tidak dan masukkan ke ApplicationDbContext publik Anda (): base ("IdentityDbContext", throwIfV1Schema: false) {} Itulah yang memicu kesalahan saya seperti milik Anda (saya punya string EF di sana). String koneksi kedua adalah yang dibuat dari menambahkan EF menggunakan wizard dan meminta parameter string Connection. Saya harap ini membantu seseorang.
JustJohn
sama disini. sangat membuat frustrasi
Nick Molyneux
1
Saya meng-upgrade dari EF 4.xke EF 6. Saya harus membuat ulang string koneksi untuk menambahkan tabel ( DatabaseFirst). Saya tidak melihat bahwa koneksi saya di app.configdan web.configberbeda. Setelah saya mengambil alih connectionstringdari app.config, mulai bekerja.
DHFW
16

Bagi saya masalahnya adalah bahwa saya belum memasukkan Kelas Entitas ke dalam db saya yang diatur dalam konteks kerangka entitas.

public DbSet<ModelName> ModelName { get; set; }
Demodave
sumber
12

Anda dapat mencoba menghapus tabel dari model dan menambahkannya lagi. Anda dapat melakukan ini secara visual dengan membuka file .edmx dari Solution Explorer.

Langkah:

  1. Klik dua kali file .edmx dari Solution Explorer
  2. Klik kanan pada kepala tabel yang ingin Anda hapus dan pilih "Hapus dari Model"
  3. Sekarang lagi klik kanan pada area kerja dan pilih "Perbarui Model dari Database .."
  4. Tambahkan tabel lagi dari daftar tabel
  5. Bersihkan dan bangun solusinya
Arun
sumber
8
Tidak ada .edmx dalam Kode EF terlebih dahulu.
Tuukka Haapaniemi
Saya memberi +1, karena dia (atau orang lain dengan masalah ini) mungkin ingin berpikir ulang melakukan Kode Dahulu dan melakukannya dengan cara ini, sebagai gantinya :)
vapcguy
9

Masalahnya mungkin pada string koneksi. Pastikan string koneksi Anda untuk penyedia SqlClient, tanpa hal-hal metadata yang terkait dengan EntityFramework.

Shawn de Wet
sumber
Ini mungkin jelas bagi banyak orang, tetapi ini akhirnya menjadi masalah saya (mengenai pencampuran db-first dengan code-first). Sekarang saya bisa berhenti memutar roda saya, terima kasih banyak!
Bonez024
3

Saya telah melihat kesalahan ini ketika tabel yang ada di database tidak secara tepat memetakan ke model kode pertama. Secara khusus saya punya char (1) di tabel database dan char di C #. Mengubah model ke string menyelesaikan masalah.

Daniel Leach
sumber
3

Masalah saya diatasi dengan memperbarui bagian metadata dari string koneksi. Rupanya itu menunjuk pada referensi .csdl / .ssdl / .msl yang salah.

ragnarswanson
sumber
Ini juga terjadi pada saya. Saya telah menyalin tali koneksi EF dari tempat lain dan belum memperbarui nama model dalam data meta.
devC
2

Satu hal lagi yang perlu diperiksa dengan string koneksi Anda - nama model. Saya menggunakan dua model entitas, DB pertama. Dalam konfigurasi saya menyalin koneksi entitas untuk satu, menamainya, dan mengubah bagian string koneksi. Apa yang tidak saya ubah adalah nama model, jadi ketika model entitas dihasilkan dengan benar, ketika konteksnya dimulai, EF mencari model yang salah untuk entitas tersebut.

Tampak jelas ditulis, tetapi ada empat jam saya tidak akan kembali.

Eddie
sumber
2

Bagi saya masalahnya adalah bahwa saya menggunakan yang connection stringdihasilkan oleh ADO.NetModel (.edmx). Mengubah string koneksi menyelesaikan masalah saya.

FN90
sumber
1

Ini juga dapat terjadi jika Anda menggunakan cache model yang ada yang ketinggalan zaman karena satu dan lain alasan. Jika konteks Anda telah di-cache ke file EDMX pada sistem file (melalui DbConfiguration.SetModelStore) maka OnModelCreating tidak akan pernah dipanggil karena versi cache akan digunakan. Akibatnya jika suatu entitas hilang dari toko cache Anda maka Anda akan mendapatkan kesalahan di atas meskipun string koneksi sudah benar, tabel ada di database dan entitas diatur dengan benar di DbContext Anda.

strickt01
sumber
1

Pesannya cukup jelas tapi saya tidak mengerti pada awalnya ...

Saya bekerja dengan dua konteks DB Entity Framework sysContextdanshardContext dalam metode yang sama.

Entitas yang telah saya modifikasi \ update berasal dari satu konteks, tetapi kemudian saya mencoba menyimpannya ke konteks lain seperti ini:

invite.uid = user.uid;

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

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

tetapi versi yang benar adalah ini:

invite.uid = user.uid;

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

shardContext.SaveChanges();

Setelah melewati entitas ke konteks yang benar kesalahan ini hilang.

Leniel Maccaferri
sumber
0

Kedengarannya jelas, tetapi pastikan Anda tidak mengabaikan jenisnya secara eksplisit:

modelBuilder.Ignore<MyType>();

emragin
sumber
0

peta entitas (bahkan yang kosong) yang ditambahkan ke konfigurasi akan menyebabkan jenis entitas menjadi bagian dari konteks. Kami memiliki entitas yang tidak memiliki hubungan dengan entitas lain yang diperbaiki dengan peta kosong.

mcfea
sumber
0

jika Anda mencoba DB terlebih dahulu maka pastikan bahwa tabel Anda memiliki kunci utama

Mahmoud
sumber
0

Visual Studio 2019 sepertinya menyebabkan ini untuk saya. Saya memperbaikinya dengan menghasilkan model edmx lagi pada tahun 2017.

chinupson
sumber
0

Saya mendapatkan masalah yang sama di Entity Framewrok dan saya menyelesaikannya dengan langkah-langkah:

1-Buka Model.edmx Anda 2-ubah tempat tabel (untuk mengubah file cs) 3-simpan

Saya harap membantu Anda

Akbar Asghari
sumber
0

Hapus file .edmx dan tambahkan lagi. Terutama, jika Anda telah meningkatkan Kerangka Kerja Entity.

Roy Oliver
sumber
0

Saya menghadapi masalah yang sama dengan EntityFrameworkCore mencoba memperbarui berbagai nilai.

Pendekatan ini tidak berhasil

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

Setelah menambahkan metode UpdateRange dan menghapus melampirkan dan memasukkan semuanya berfungsi

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

Bagi saya itu disebabkan karena saya mengganti nama kelas entitas. Ketika saya mengembalikannya, itu ok.

Iván Kollár
sumber
0

Bisa jadi bodoh, tetapi jika Anda hanya mendapatkan kesalahan ini pada beberapa Tabel, jangan lupa untuk membersihkan proyek Anda dan membangun kembali (bisa menghemat banyak waktu)

LeBigCat
sumber
0

Saya punya ini

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

Ini dalam metode async, tapi saya lupa menunggu sebelum GetEntryAsync, dan jadi saya mendapatkan kesalahan yang sama ini ...

bifedefrango
sumber