Il tipo di entità <tipo> non fa parte del modello per il contesto corrente


147

Sto entrando in Entity Framework, ma non sono sicuro di perdere un punto critico nell'approccio basato sul codice.

Sto usando un modello di repository generico basato sul codice di https://genericunitofworkandrepositories.codeplex.com/ e ho creato le mie entità.

Ma quando provo ad accedere o modificare l'entità mi imbatto nel seguente:

System.InvalidOperationException: il tipo di entità Estate non fa parte del modello per il contesto corrente.

Succede quando sto provando ad accedervi dal mio repository:

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

Il database (./SQLEXPRESS) viene creato bene, ma le entità (tabelle) non vengono create all'avvio.

Mi chiedo se devo impostare esplicitamente la mappatura delle entità? EF non è in grado di farlo da solo?

La mia entità è:

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

Il mio contesto è così:

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

}

C'è un motivo specifico per cui si verifica questo errore? Ho provato ad abilitare le migrazioni e abilitare le migrazioni automatiche senza alcun aiuto.

Risposte:


143

Inserisci questo nella tua DbContextclasse personalizzata :

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

Se le tabelle non vengono create all'avvio, questo è il motivo. È necessario informarne il DbContext nella sostituzione del metodo OnModelCreating.

È possibile eseguire mappature personalizzate per entità qui o separarle in EntityTypeConfiguration<T>classi separate .


1
Grazie, Dan - questo risolve il problema. Ora le tabelle sono state create. Non c'è altro modo, EF non può farlo da solo? Non posso semplicemente annotare l'entità con [ToTable ('Estates')] o qualcosa del genere?
Janhartmann,

3
Penso che potrebbe funzionare senza ignorare OnModelCreatingse le tue entità si trovano nello stesso assembly della tua DbContext. Non ho mai usato le annotazioni dei dati per le entità, quindi non posso dirlo con certezza. Puoi sempre scansionare assiemi nel tuo OnModelCreatingper trovare entità in altri assiemi e registrarli automaticamente (che è ciò che fa il treppiede).
danludwig,

Ah certo. Grazie per la nota sul modo in cui treppiede di farlo, ho fatto qualcosa di simile ora e sembra funzionare bene. (anche grazie alle estensioni di riflessione su: github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/… ). Ora ho solo bisogno che trovi gli assembly di riferimento invece di cercare nell'assembly GetType (). "var assembly = Assembly.Load (" Dimension.Web.Domain ");" non è carino ;-)
Janhartmann il

O forse basta spostare la mia nuova cartella / Mapping / nel mio progetto Impl anziché nel mio dominio.
Janhartmann,

@meep o danludwig. Potete per favore dirmi di più su Treppiede o condividere un link.
DkAngelito,

73

Apparentemente, questo errore è molto generico, potrebbe avere una serie di motivi. Nel mio caso, è stato il seguente: La stringa di connessione (in Web.config) generata da .edmxnon era valida. Dopo quasi un giorno di tentativi, ho cambiato la stringa di connessione dalla stringa EF a una stringa ADO.NET. Questo ha risolto il mio problema.

Ad esempio, la stringa EF ha un aspetto simile al seguente:

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

E la stringa ADO.NET si presenta così:

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

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


17
Il mio problema era anche nella stringa di connessione. Avevo rinominato il mio modello di dati e riprovato i miei modelli t4, ma ho dimenticato di aggiornare i metadati (file .csdl, .ssdl, .msl) nella stringa di connessione. La tua risposta mi ha aiutato a capire questo, quindi grazie!
Vyskol,

4
Se si utilizza il modello Identity per l'autenticazione sono necessarie 2 stringhe di connessioni: una, la "DefaultConnection" che è possibile rinominare o meno e inserire nel proprio ApplicationDbContext pubblico (): base ("IdentityDbContext", throwIfV1Schema: false) {} Ecco cosa ha causato il mio errore come il tuo (avevo la stringa EF lì dentro). La seconda stringa di connessione è quella creata dall'aggiunta di EF tramite la procedura guidata e richiede i parametri della stringa di connessione. Spero che questo aiuti qualcuno.
JustJohn,

anch'io. incredibilmente frustrante
Nick Molyneux il

1
Aggiornamento da EF 4.xa EF 6. Ho dovuto rigenerare la stringa di connessione per aggiungere una tabella ( DatabaseFirst). Non ho notato che le mie stringhe di connessione nel app.confige il web.configerano diverse. Una volta che ho preso il comando connectionstringdal app.config, ha iniziato a funzionare.
DHFW,

16

Per me il problema era che non avevo incluso la Classe di entità all'interno del mio db set nel contesto del framework di entità.

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

12

Puoi provare a rimuovere la tabella dal modello e aggiungerla di nuovo. Puoi farlo visivamente aprendo il file .edmx da Esplora soluzioni.

passi:

  1. Fare doppio clic sul file .edmx da Esplora soluzioni
  2. Fare clic con il tasto destro del mouse sull'intestazione della tabella che si desidera rimuovere e selezionare "Elimina dal modello"
  3. Ora di nuovo fai clic con il pulsante destro del mouse sull'area di lavoro e seleziona "Aggiorna modello dal database .."
  4. Aggiungi nuovamente la tabella dall'elenco delle tabelle
  5. Pulisci e costruisci la soluzione

8
Non esiste prima .edmx nel codice EF.
Tuukka Haapaniemi,

Ho dato un +1, però, perché lui (o qualcun altro con questo problema) potrebbe voler ripensarci facendo Code First e farlo in questo modo, invece :)
vapcguy

9

Il problema potrebbe essere nella stringa di connessione. Assicurarsi che la stringa di connessione sia per il provider SqlClient, senza elementi di metadati relativi a EntityFramework.


Questo era probabilmente ovvio per molti, ma questo è stato il mio problema (riguardo al mescolare db-first con code-first). Ora posso smettere di girare le ruote, grazie mille!
Bonez024

3

Ho visto questo errore quando una tabella esistente nel database non è correttamente mappata su un primo modello di codice. Nello specifico avevo un carattere (1) nella tabella del database e un carattere in C #. La modifica del modello in una stringa ha risolto il problema.


3

Il mio problema è stato risolto aggiornando la parte dei metadati della stringa di connessione. Apparentemente puntava al riferimento .csdl / .ssdl / .msl sbagliato.


Questo è successo anche a me. Avevo copiato la stringa di connessione EF da qualche altra parte e non avevo aggiornato il nome del modello nei metadati.
devC

2

Un'altra cosa da verificare con la stringa di connessione: il nome del modello. Stavo usando due modelli di entità, prima DB. Nella configurazione ho copiato la connessione dell'entità per una, l'ho rinominata e ho cambiato la parte della stringa di connessione. Quello che non ho cambiato è stato il nome del modello, quindi mentre il modello dell'entità è stato generato correttamente, quando il contesto è stato avviato EF cercava le entità nel modello sbagliato.

Sembra ovvio scritto, ma ci sono quattro ore che non torno indietro.


2

Per me il problema era che ho usato il connection stringgenerato da ADO.NetModel (.edmx). La modifica della stringa di connessione ha risolto il mio problema.


1

Ciò può verificarsi anche se si utilizza una cache del modello persistente che non è aggiornata per un motivo o per l'altro. Se il tuo contesto è stato memorizzato nella cache in un file EDMX su un file system (tramite DbConfiguration.SetModelStore), OnModelCreating non verrà mai chiamato poiché verrà utilizzata la versione cache. Di conseguenza se un'entità non è presente nel negozio memorizzato nella cache, si otterrà l'errore sopra riportato anche se la stringa di connessione è corretta, la tabella esiste nel database e l'entità è impostata correttamente nel DbContext.


1

Il messaggio era abbastanza chiaro ma all'inizio non l'ho capito ...

Sto lavorando con due contesti Entity Framework DB sysContexte shardContextcon lo stesso metodo.

L'entità che avevo modificato \ aggiornato proviene da un contesto ma poi ho provato a salvarlo nell'altro contesto in questo modo:

invite.uid = user.uid;

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

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

ma la versione corretta dovrebbe essere questa:

invite.uid = user.uid;

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

shardContext.SaveChanges();

Dopo aver passato l'entità al contesto corretto, questo errore è scomparso.


0

Sembra ovvio, ma assicurati di non ignorare esplicitamente il tipo:

modelBuilder.Ignore<MyType>();


0

la mappa dell'entità (anche vuota) aggiunta alla configurazione farà sì che il tipo di entità faccia parte del contesto. Avevamo un'entità senza relazione con altre entità che era stata riparata con una mappa vuota.


0

se stai provando DB per primo, assicurati che la tua tabella abbia la chiave primaria


0

Visual Studio 2019 sembra causare questo per me. L'ho risolto generando di nuovo il modello edmx nel 2017.


0

Ottengo lo stesso problema in Entity Framewrok e l'ho risolto seguendo i passaggi:

1-Apri il tuo Model.edmx 2-cambia un posto tabella (per fare il cambiamento nel file cs) 3-salvalo

Spero di aiutarti


0

Elimina il file .edmx e aggiungilo di nuovo. Soprattutto se hai aggiornato Entity Framework.


0

Stavo affrontando lo stesso problema con EntityFrameworkCore nel tentativo di aggiornare un intervallo di valori.

Questo approccio non ha funzionato

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

Dopo l'aggiunta del metodo UpdateRange e la rimozione di attach e entry tutto funziona

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

0

Per me è stato causato perché ho rinominato la classe di entità. Quando l'ho ripristinata era OK.


0

Potrebbe essere stupido, ma se hai solo questo errore su qualche Tavolo, non dimenticare di pulire il tuo progetto e ricostruire (potrebbe risparmiare un sacco di tempo)


0

Ho avuto questo

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

Questo era in un metodo asincrono, ma ho dimenticato di aspettare prima di GetEntryAsync, e quindi ho avuto lo stesso errore ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.