Der Entitätstyp <Typ> ist nicht Teil des Modells für den aktuellen Kontext

146

Ich komme in das Entity Framework, bin mir aber nicht sicher, ob mir ein kritischer Punkt im Code-First-Ansatz fehlt.

Ich verwende ein generisches Repository-Muster, das auf dem Code von https://genericunitofworkandrepositories.codeplex.com/ basiert, und habe meine Entitäten erstellt.

Wenn ich jedoch versuche, auf die Entität zuzugreifen oder sie zu ändern, stoße ich auf Folgendes:

System.InvalidOperationException: Der Entitätstyp Estate ist nicht Teil des Modells für den aktuellen Kontext.

Es passiert, wenn ich versuche, von meinem Repository aus darauf zuzugreifen:

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

Die Datenbank (./SQLEXPRESS) wird einwandfrei erstellt, aber die Entitäten (Tabellen) werden beim Start einfach nicht erstellt.

Ich frage mich, ob ich die Zuordnung der Entitäten explizit festlegen muss. Kann EF das nicht alleine?

Mein Wesen ist:

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

Mein Kontext ist wie folgt:

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

}

Gibt es einen bestimmten Grund, warum dieser Fehler auftritt? Ich habe versucht, Migrationen zu aktivieren und automatische Migrationen auch ohne Hilfe zu aktivieren.

janhartmann
quelle

Antworten:

141

Fügen Sie dies in Ihre benutzerdefinierte DbContextKlasse ein:

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

Wenn Ihre Tabellen beim Start nicht erstellt werden, ist dies der Grund. Sie müssen den DbContext in der OnModelCreating-Methodenüberschreibung darüber informieren.

Sie können hier entweder benutzerdefinierte Zuordnungen pro Entität vornehmen oder diese in separate EntityTypeConfiguration<T>Klassen aufteilen.

danludwig
quelle
1
Danke, Dan - das behebt es. Jetzt werden die Tabellen erstellt. Es gibt keinen anderen Weg, EF kann das nicht alleine machen? Ich kann die Entität nicht einfach mit [ToTable ('Estates')] oder so etwas kommentieren?
Janhartmann
3
Ich denke, das könnte ohne Überschreiben funktionieren, OnModelCreatingwenn sich Ihre Entitäten in derselben Assembly wie Ihre befinden DbContext. Ich habe jedoch noch nie Datenanmerkungen für Entitäten verwendet, daher kann ich nicht sicher sagen. Sie können Baugruppen in Ihrer Baugruppe jederzeit scannen OnModelCreating, um Entitäten in anderen Baugruppen zu finden und diese automatisch zu registrieren (was Tripod tut).
Danludwig
Ah natürlich. Vielen Dank für den Hinweis zur Vorgehensweise auf dem Stativ. Ich habe jetzt etwas Ähnliches getan, und es scheint gut zu funktionieren. (auch dank Ihrer Reflexionserweiterungen auf: github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/… ). Jetzt muss ich nur noch Referenzassemblys finden, anstatt die GetType () - Assembly zu durchsuchen. "var Assembly = Assembly.Load (" Dimension.Web.Domain ");" ist nicht schön ;-)
janhartmann
Oder verschieben Sie einfach meinen neuen Ordner / Mapping / in mein Impl-Projekt anstelle meiner Domain.
Janhartmann
@meep oder danludwig. Kannst du mir bitte mehr über Tripod erzählen oder mir einen Link geben?
DkAngelito
73

Anscheinend ist dieser Fehler sehr allgemein gehalten und kann mehrere Gründe haben. In meinem Fall war es das Folgende: Die von der generierte Verbindungszeichenfolge (in Web.config) .edmxwar ungültig. Nachdem ich fast einen Tag lang alles ausprobiert hatte, änderte ich die Verbindungszeichenfolge von der EF-Zeichenfolge in eine ADO.NET-Zeichenfolge. Dies löste mein Problem.

Die EF-Zeichenfolge sieht beispielsweise folgendermaßen aus:

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

Und die ADO.NET-Zeichenfolge sieht folgendermaßen aus:

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

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

Christiaan Maks
quelle
17
Mein Problem war auch in der Verbindungszeichenfolge. Ich hatte mein Datenmodell umbenannt und meine t4-Vorlagen erneut sortiert, aber vergessen, die Metadaten (CSDL-, SSDL-, MSL-Dateien) in der Verbindungszeichenfolge zu aktualisieren. Ihre Antwort hat mir geholfen, dies zu realisieren. Vielen Dank!
Vyskol
4
Wenn Sie das Identitätsmodell zur Authentifizierung verwenden, benötigen Sie zwei Verbindungszeichenfolgen: eine, die "DefaultConnection", die Sie umbenennen können oder nicht, und die Sie in Ihren öffentlichen ApplicationDbContext (): base ("IdentityDbContext", throwIfV1Schema: false) {} einfügen. Dies hat meinen Fehler ausgelöst wie deine (ich hatte die EF-Saite drin). Die zweite Verbindungszeichenfolge besteht aus dem Hinzufügen von EF mithilfe des Assistenten und fragt nach Verbindungszeichenfolgenparametern. Ich hoffe das hilft jemandem.
JustJohn
hier gilt das gleiche. unglaublich frustrierend
Nick Molyneux
1
Ich aktualisiere von EF 4.xauf EF 6. Ich musste die Verbindungszeichenfolge neu generieren, um eine Tabelle ( DatabaseFirst) hinzuzufügen . Ich habe nicht bemerkt, dass meine Verbindungsschnur in der app.configund die web.configunterschiedlich waren. Nachdem ich das connectionstringvon übernommen hatte app.config, fing es an zu funktionieren.
DHFW
16

Für mich bestand das Problem darin, dass ich die Entitätsklasse nicht in meine Datenbank aufgenommen hatte, die im Kontext für das Entitätsframework enthalten war.

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

Sie können versuchen, die Tabelle aus dem Modell zu entfernen und erneut hinzuzufügen. Sie können dies visuell tun, indem Sie die EDMX-Datei im Projektmappen-Explorer öffnen.

Schritte:

  1. Doppelklicken Sie im Projektmappen-Explorer auf die EDMX-Datei
  2. Klicken Sie mit der rechten Maustaste auf den Tabellenkopf, den Sie entfernen möchten, und wählen Sie "Aus Modell löschen".
  3. Klicken Sie nun erneut mit der rechten Maustaste auf den Arbeitsbereich und wählen Sie "Modell aus Datenbank aktualisieren".
  4. Fügen Sie die Tabelle erneut aus der Tabellenliste hinzu
  5. Reinigen und bauen Sie die Lösung
Arun
quelle
8
Es gibt zuerst keine .edmx im EF-Code.
Tuukka Haapaniemi
Ich gab jedoch eine +1, weil er (oder jemand anderes mit diesem Problem) vielleicht
überlegen
9

Das Problem liegt möglicherweise in der Verbindungszeichenfolge. Stellen Sie sicher, dass Ihre Verbindungszeichenfolge für den SqlClient-Anbieter bestimmt ist und keine Metadaten mit EntityFramework verknüpft sind.

Shawn de Wet
quelle
Dies war wahrscheinlich für viele offensichtlich, aber dies war mein Problem (in Bezug auf das Mischen von db-first mit code-first). Jetzt kann ich aufhören, meine Räder zu drehen, großes Dankeschön!
Bonez024
3

Ich habe diesen Fehler gesehen, wenn eine vorhandene Tabelle in der Datenbank einem Code-First-Modell nicht angemessen zugeordnet ist. Insbesondere hatte ich ein Zeichen (1) in der Datenbanktabelle und ein Zeichen in C #. Das Ändern des Modells in eine Zeichenfolge hat das Problem behoben.

Daniel Leach
quelle
3

Mein Problem wurde behoben, indem der Metadatenteil der Verbindungszeichenfolge aktualisiert wurde. Anscheinend zeigte es auf die falsche .csdl / .ssdl / .msl-Referenz.

Ragnarswanson
quelle
Das ist mir auch passiert. Ich hatte den EF-Verbindungsstring von einem anderen Ort kopiert und den Modellnamen in den Metadaten nicht aktualisiert.
devC
2

Eine andere Sache, die Sie mit Ihrer Verbindungszeichenfolge überprüfen sollten - den Modellnamen. Ich habe zwei Entitätsmodelle verwendet, zuerst DB. In der Konfiguration habe ich die Entitätsverbindung für eine kopiert, umbenannt und den Teil der Verbindungszeichenfolge geändert. Was ich nicht geändert habe, war der Modellname. Während das Entitätsmodell korrekt generiert wurde, suchte EF beim Initiieren des Kontexts im falschen Modell nach den Entitäten.

Sieht offensichtlich aufgeschrieben aus, aber es gibt vier Stunden, in denen ich nicht zurückkomme.

Eddie
quelle
2

Für mich war das Problem, dass ich das connection stringvon ADO.NetModel (.edmx) generierte verwendet habe. Das Ändern der Verbindungszeichenfolge hat mein Problem behoben.

FN90
quelle
1

Dies kann auch auftreten, wenn Sie einen persistenten Modellcache verwenden, der aus dem einen oder anderen Grund veraltet ist. Wenn Ihr Kontext in einer EDMX-Datei in einem Dateisystem zwischengespeichert wurde (über DbConfiguration.SetModelStore), wird OnModelCreating niemals aufgerufen, da die zwischengespeicherte Version verwendet wird. Wenn eine Entität in Ihrem zwischengespeicherten Speicher fehlt, wird der obige Fehler angezeigt, obwohl die Verbindungszeichenfolge korrekt ist, die Tabelle in der Datenbank vorhanden ist und die Entität in Ihrem DbContext korrekt eingerichtet ist.

strickt01
quelle
1

Die Nachricht war ziemlich klar, aber ich habe sie zuerst nicht verstanden ...

Ich arbeite mit zwei Entity Framework DB-Kontexten sysContextund shardContextin derselben Methode.

Die Entität, die ich geändert oder aktualisiert habe, stammt aus einem Kontext, aber dann habe ich versucht, sie wie folgt im anderen Kontext zu speichern:

invite.uid = user.uid;

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

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

aber die richtige Version sollte folgende sein:

invite.uid = user.uid;

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

shardContext.SaveChanges();

Nachdem die Entität an den richtigen Kontext übergeben wurde, wurde dieser Fehler behoben.

Leniel Maccaferri
quelle
0

Klingt offensichtlich, aber stellen Sie sicher, dass Sie den Typ nicht explizit ignorieren:

modelBuilder.Ignore<MyType>();

Emragine
quelle
0

Eine Karte der Entität (auch eine leere), die der Konfiguration hinzugefügt wurde, führt dazu, dass der Entitätstyp Teil des Kontexts ist. Wir hatten eine Entität ohne Beziehung zu anderen Entitäten, die mit einer leeren Karte behoben wurde.

mcfea
quelle
0

Wenn Sie zuerst DB versuchen, stellen Sie sicher, dass Ihre Tabelle über einen Primärschlüssel verfügt

Mahmoud
quelle
0

Visual Studio 2019 scheint dies für mich zu verursachen. Ich habe es behoben, indem ich das edmx-Modell 2017 erneut generiert habe.

Chinupson
quelle
0

Ich habe das gleiche Problem in Entity Framewrok und habe es folgendermaßen gelöst:

1-Öffnen Sie Ihre Model.edmx 2-ändern Sie einen Tabellenplatz (zum Ändern in der cs-Datei) 3-speichern Sie ihn

Ich hoffe dir zu helfen

Akbar Asghari
quelle
0

Löschen Sie die .edmx-Datei und fügen Sie sie erneut hinzu. Insbesondere, wenn Sie das Entity Framework aktualisiert haben.

Roy Oliver
quelle
0

Ich hatte das gleiche Problem mit EntityFrameworkCore, das versuchte, einen Wertebereich zu aktualisieren.

Dieser Ansatz hat nicht funktioniert

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

Nach dem Hinzufügen der UpdateRange-Methode und dem Entfernen von Anhängen und Eingeben funktioniert alles

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

Für mich wurde es verursacht, weil ich die Entitätsklasse umbenannt habe. Als ich sie zurückrollte, war es in Ordnung.

Iván Kollár
quelle
0

Könnte dumm sein, aber wenn Sie diesen Fehler nur in einer Tabelle haben, vergessen Sie nicht, Ihr Projekt zu bereinigen und neu zu erstellen (könnte viel Zeit sparen)

LeBigCat
quelle
0

Ich hatte das

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

Dies war eine asynchrone Methode, aber ich habe vergessen, vor GetEntryAsync zu warten, und so habe ich den gleichen Fehler erhalten ...

bifedefrango
quelle