<Tür> varlık türü, geçerli bağlam için modelin bir parçası değil


147

Entity Framework içine alıyorum, ama kod ilk yaklaşımda kritik bir noktayı eksik olup olmadığından emin değilim.

Https://genericunitofworkandrepositories.codeplex.com/ adresindeki koda dayalı genel bir depo deseni kullanıyorum ve varlıklarımı oluşturdum.

Ancak varlığa erişmeye veya değiştirmeye çalıştığımda aşağıdakilerle karşılaşıyorum:

System.InvalidOperationException: Estate varlık türü, geçerli bağlam için modelin bir parçası değil.

Depomdan erişmeye çalıştığımda olur:

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

Veritabanı (./SQLEXPRESS) gayet iyi oluşturulmuş, ancak varlıklar (tablolar) başlangıçta oluşturulmamış.

Varlıkları eşleştirmeyi açıkça ayarlamam gerekip gerekmediğini merak ediyorum? EF bunu tek başına yapamıyor mu?

Varlığım:

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

Bağlamım şöyle:

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

}

Bu hatanın oluşmasının belirli bir nedeni var mı? Herhangi bir yardım almadan geçişleri etkinleştirmeyi ve otomatik geçişleri etkinleştirmeyi denedim.

Yanıtlar:


143

Bunu özel DbContextsınıfınıza koyun :

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

Tablolarınız başlangıçta oluşturulmamışsa, bu nedenle. OnModelCreating yöntemini geçersiz kılmada DbContext'i bunlar hakkında söylemeniz gerekir.

Burada özel varlık başına eşlemeler yapabilir veya ayrı EntityTypeConfiguration<T>sınıflara ayırabilirsiniz .


1
Teşekkürler Dan - bu sorunu çözer. Şimdi tablolar oluşturuldu. Etrafında başka bir yol yok, EF bunu kendi başına yapamaz mı? Varlığa sadece [ToTable ('Estates')] veya benzeri bir şeyle açıklama ekleyemiyorum?
janhartmann

3
Varlıklarınız OnModelCreatingsizinle aynı derlemedeyse, bu geçersiz kılmadan işe yarayabilir diye düşünüyorum DbContext. Varlıklar için veri ek açıklamaları hiç kullanmadım, bu yüzden kesin olarak söyleyemem. OnModelCreatingDiğer montajlardaki varlıkları bulmak ve her zaman otomatik olarak (Tripod'un yaptığı şey) kaydetmek için montajlarınızı her zaman tarayabilirsiniz .
danludwig

Ah, elbette. Tripod'u yapmanın yolu hakkında not için teşekkürler, şimdi benzer bir şey yaptım ve gayet iyi çalışıyor gibi görünüyor. (ayrıca github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/… adresindeki yansıma uzantılarınız sayesinde ). Şimdi sadece GetType () derleme olsa bakmak yerine başvuruları derlemeleri bulmak gerekir. "var assembly = Assembly.Load (" Dimension.Web.Domain ");" hoş değil ;-)
janhartmann

Ya da sadece yeni / Mapping / klasörümü Etki Alanım yerine Impl projeme taşıyın.
janhartmann

@meep veya danludwig. Lütfen bana Tripod hakkında daha fazla bilgi verebilir veya bana bir bağlantı paylaşabilir misiniz?
DkAngelito

73

Görünüşe göre, bu hata çok genel, bir takım nedenleri olabilir. Benim durumumda, bu oldu: tarafından oluşturulan bağlantı dizesi (Web.config içinde) .edmxgeçersizdi. Neredeyse her şeyi denedikten bir gün sonra, bağlantı dizesini EF dizesinden bir ADO.NET dizesine değiştirdim. Bu benim sorunumu çözdü.

Örneğin, EF dizesi şöyle görünür:

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

Ve ADO.NET dizesi şöyle görünür:

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

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


17
Benim sorunum da bağlantı dizesinde oldu. Veri modelimi yeniden adlandırdım ve t4 şablonumu yeniden düzenledim, ancak bağlantı dizesindeki meta verileri (.csdl, .ssdl, .msl dosyaları) güncellemeyi unuttum. Cevabınız bunu anlamama yardımcı oldu, bu yüzden teşekkür ederim!
Vyskol

4
Kimlik doğrulama için Kimlik modeli kullanıyorsanız, 2 bağlantı dizesine ihtiyacınız vardır: biri, yeniden adlandırıp değiştiremeyeceğiniz ve genel ApplicationDbContext (): base ("IdentityDbContext") içine atabileceğiniz "DefaultConnection" seninki gibi (ben orada EF dize vardı). İkinci bağlantı dizesi, sihirbaz kullanılarak EF eklenerek yapılan dizgidir ve Bağlantı dizesi parametrelerini ister. Umarım bu birine yardımcı olur.
JustJohn

burada aynı. inanılmaz sinir bozucu
Nick Molyneux

1
- 'dan EF 4.xyükseliyorum EF 6. Bir tablo ( DatabaseFirst) eklemek için bağlantı dizesini yeniden oluşturmak zorunda kaldı . Ben benim ConnectionString o haber vermedi app.configve web.configfarklıydı. Ben devralması connectionstringgelen app.config, bu çalışmaya başladı.
DHFW

16

Benim için sorun, varlık çerçevesinin bağlamı içinde ayarlanmış benim db içinde Varlık Sınıfı dahil etmemişti.

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

12

Tabloyu modelden kaldırmayı ve tekrar eklemeyi deneyebilirsiniz. Bunu, Çözüm Gezgini'nden .edmx dosyasını açarak görsel olarak yapabilirsiniz.

Adımlar:

  1. Solution Explorer'dan .edmx dosyasını çift tıklatın
  2. Kaldırmak istediğiniz tablo başlığına sağ tıklayın ve "Modelden Sil" i seçin
  3. Şimdi tekrar çalışma alanına sağ tıklayın ve "Modeli Veritabanından Güncelle" yi seçin.
  4. Tabloyu tablo listesinden tekrar ekleyin
  5. Çözümü temizleyin ve oluşturun

8
Önce EF Kodunda .edmx yoktur.
Tuukka Haapaniemi

Yine de +1 verdim, çünkü o (veya bu sorunu olan bir başkası) Önce Kod yapmayı yeniden düşünmek ve bunun yerine bunu yapmak
isteyebilir

9

Sorun bağlantı dizesinde olabilir. Bağlantı dizenizin, EntityFramework ile ilgili meta veri öğesi olmadan SqlClient sağlayıcısı için olduğundan emin olun.


Bu muhtemelen birçokları için açıktı, ama bu benim sorunum oldu (db-ilk kod ilk ile karıştırma ile ilgili). Şimdi tekerleklerimi döndürmeyi bırakabilirim, büyük teşekkür ederim!
Bonez024

3

Veritabanındaki mevcut bir tablo uygun bir kod ilk modeliyle eşleşmediğinde bu hatayı gördüm. Özellikle veritabanı tablosunda bir char (1) ve C # 'da bir char vardı. Modeli bir dizeye değiştirmek sorunu çözdü.


3

Sorunum bağlantı dizesinin meta veri bölümü güncelleştirilerek giderildi. Görünüşe göre yanlış .csdl / .ssdl / .msl referansına işaret ediyordu.


Bu da bana oldu. EF bağlantılarını başka bir yerden kopyaladım ve meta verilerdeki model adını güncellememiştim.
devC

2

Bağlantı dizenizle kontrol edilmesi gereken bir şey daha var - model adı. Önce DB olmak üzere iki varlık modeli kullanıyordum. Yapılandırmada varlık bağlantısını biri için kopyaladım, yeniden adlandırdım ve bağlantı dizesi parçasını değiştirdim. Değiştirmediğim şey model adıydı, bu yüzden varlık modeli doğru bir şekilde oluşturulmuşken, bağlam başlatıldığında EF varlıklar için yanlış modele bakıyordu.

Yazılı gibi görünüyor ama geri dönmeyeceğim dört saat var.


2

Benim için sorun, Model (.edmx) connection stringtarafından oluşturulan benim kullandım oldu ADO.Net. Bağlantı dizesini değiştirmek sorunumu çözdü.


1

Bu, bir nedenden ötürü güncel olmayan kalıcı bir model önbellek kullanıyorsanız da oluşabilir. Bağlamınız bir dosya sistemindeki (DbConfiguration.SetModelStore aracılığıyla) bir EDMX dosyasına önbelleğe alınmışsa, önbelleğe alınan sürüm kullanılacağı için OnModelCreating hiçbir zaman çağrılmaz. Sonuç olarak, bir varlık önbelleğe alınmış deponuzda eksikse, bağlantı dizesi doğru olsa bile yukarıdaki hatayı alırsınız, tablo veritabanında bulunur ve varlık DbContext'inizde doğru şekilde ayarlanır.


1

Mesaj çok açıktı ama ilk başta anlayamadım ...

İki Entity Framework DB bağlamları sysContextve shardContextaynı yöntemle çalışıyorum.

Değiştirdiğim \ güncellendi varlık bir bağlamdan ancak sonra bu gibi diğer bağlama kaydetmek için çalıştı:

invite.uid = user.uid;

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

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

ancak doğru sürüm şu olmalıdır:

invite.uid = user.uid;

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

shardContext.SaveChanges();

Varlığı doğru bağlama geçirdikten sonra bu hata ortadan kalktı.


0

Açık görünüyor, ancak türü açıkça görmezden gelmediğinizden emin olun:

modelBuilder.Ignore<MyType>();


0

konfigürasyona eklenen varlığın haritası (boş bir tane bile) varlık türünün bağlamın bir parçası olmasına yol açacaktır. Boş bir harita ile düzeltilen diğer varlıklar ile ilişkisi olmayan bir varlığımız vardı.


0

önce DB'yi deniyorsanız, tablonuzda birincil anahtar olduğundan emin olun


0

Visual Studio 2019 buna neden oluyor gibi görünüyor. 2017'de yine edmx modelini oluşturarak düzelttim.


0

Entity Framewrok aynı sorunu alıyorum ve adımları altında çözdüm:

1-Model.edmx'inizi açın 2-tablo yerini değiştirin (cs dosyasında değişiklik yapmak için) 3-kaydedin

Umarım sana yardım eder


0

.Edmx dosyasını silin ve tekrar ekleyin. Özellikle Varlık Çerçevesini yükselttiyseniz.


0

EntityFrameworkCore bir dizi değeri güncellemeye çalışırken aynı sorunla karşı karşıyaydım.

Bu yaklaşım işe yaramadı

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

UpdateRange yöntemini ekledikten ve ekleme ve girişi kaldırdıktan sonra her şey işe yarıyor

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


0

Aptal olabilir, ancak bu hatayı sadece bazı Masalarda aldıysanız, projenizi temizlemeyi ve yeniden oluşturmayı unutmayın (çok zaman kazandırabilir)


0

Buna sahiptim

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

Bu bir zaman uyumsuz yöntemdi, ama GetEntryAsync önce beklemek unuttum ve böylece aynı hatayı aldım ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.