EntityType hat keinen vom Schlüssel definierten Fehler


145

Regler:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcApplication1.Controllers
{
    public class studentsController : Controller
    {
        //
        // GET: /students/

        public ActionResult details()
        {
            int id = 16;
            studentContext std = new studentContext();
           student first = std.details.Single(m => m.RollNo == id);
            return View(first);
        }

    }
}

DbContext-Modell:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;

namespace MvcApplication1.Models
{
    public class studentContext : DbContext
    {
        public DbSet<student> details { get; set; }
    }
}

Modell:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcApplication1.Models
{
    [Table("studentdetails")]
    public class student
    {
        public int RollNo;
        public string Name;
        public string Stream;
        public string Div;
    }
}

Datenbanktabelle:

CREATE TABLE [dbo].[studentdetails](
    [RollNo] [int] NULL,
    [Name] [nvarchar](50) NULL,
    [Stream] [nvarchar](50) NULL,
    [Div] [nvarchar](50) NULL
)  

In global.asax.cs

Database.SetInitializer<MvcApplication1.Models.studentContext>(null);

Der obige Code listet alle Klassen auf, an denen ich arbeite. Beim Ausführen meiner Anwendung wird folgende Fehlermeldung angezeigt:

"Ein oder mehrere Validierungsfehler wurden während der Modellgenerierung festgestellt" zusammen mit "Entitätstyp hat keinen Schlüssel definiert".


3
Überprüfen Sie die Repository-Datei. Alle Lösungen auf dieser Seite sind erstaunlich, aber in meinem Fall habe ich alles richtig gemacht, aber vergessen, die Tabelle als DbSet zu deklarieren und sie den modelbuilder.configurations hinzuzufügen.
Tosh

In meinem Fall zeigte ich den Code auf eine andere Datenbank und die Tabelle fehlte in der Datenbank
Kristina Lex

Antworten:


168

Die Modellklasse sollte geändert werden in:

using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models
{
    [Table("studentdetails")]
    public class student
    {
        [Key]
        public int RollNo { get; set; }

        public string Name { get; set; }

        public string Stream { get; set; }

        public string Div { get; set; }
    }
}

1
Mein Code hat (ohne [Key]) funktioniert, bis ich die Datentypen geändert habe (ich habe sie geändert unsigned) und nur Byte funktioniert. Gibt es einen Grund, warum ich keine unsignedWerte verwenden kann?
Mihai Bratulescu

5
Entity Framework unterstützt keine vorzeichenlosen Ganzzahlen msdn.microsoft.com/en-us/library/vstudio/…
user2316116

1
Und falls Sie es als Modell in MVC verwenden, vergessen Sie nicht, es neu zu erstellen!
RoJaIt

1
Viele verschiedene Dinge können diesen Fehler verursachen. In meinem Fall habe ich fälschlicherweise mein "Id" -Feld "privat" anstelle von "öffentlich" markiert (eine Gewohnheit von Java / JPA). Die Antwort von Larry Raymond unten ist wohl die "beste" Antwort auf diese Frage. Es werden die meisten gängigen Szenarien hinter "EntityType hat keinen schlüsseldefinierten Fehler" aufgelistet.
Pauls4

98
  1. Stellen Sie sicher, dass öffentliche Mitglieder der Schülerklasse als Eigenschaften mit definiert sind {get; set;}(Ihre sind öffentliche Variablen - ein häufiger Fehler).

  2. Platzieren Sie eine [Key]Anmerkung auf der von Ihnen ausgewählten Immobilie.


Das war mein Problem. Vielen Dank. Ich habe eine Schnittstelle implementiert, für die nur ein Getter für die ID erforderlich ist
Henry Ing-Simmons

81

Dies kann mehrere Gründe haben. Einige davon habe ich hier gefunden , andere habe ich selbst entdeckt.

  • Wenn die Eigenschaft einen anderen Namen als hat Id, müssen Sie das [Key]Attribut hinzufügen .
  • Der Schlüssel muss eine Eigenschaft sein, kein Feld.
  • Der Schlüssel muss sein public
  • Die wichtigsten Anforderungen ein CLS-konformen Typ sein, was bedeutet , unsigned Typen mögen uint, ulongusw. sind nicht erlaubt.
  • Dieser Fehler kann auch durch Konfigurationsfehler verursacht werden .

3
Ich habe auch festgestellt, dass die Schlüsseleigenschaft Lese- / Schreibzugriff sein muss. Ich habe den Fehler von OP erhalten, als ich einen Getter und keinen Setter für die ID-Eigenschaft hatte.
JohnFx

1
@ JohnFx ist absolut korrekt. Resharper wurde private setwährend einer Bereinigung von einigen Eigenschaften entfernt . Das Ergebnis war "EntityType hat keinen vom Schlüssel definierten Fehler". Achten Sie daher darauf, dass die Bereinigungstools den erforderlichen Code entfernen.
Jeremysawesome

In meinem Fall habe ich einen nicht verwandten Namen verwendet, um die ID der Klasse zu erwähnen. Das zu ändern, wie in Ihrer Lösung erwähnt, hat mein Problem gelöst.
Vielen Dank

Wenn Sie irgendeine Eigenschaft wie verwenden ID, Id, ClassNameID, ClassNameIdmüssen Sie nicht verwenden müssen[Key] attribute
Pranav Bilurkar

21

Ich weiß, dass dieser Beitrag zu spät ist, aber diese Lösung hat mir geholfen:

    [Key]
    [Column(Order = 0)]
    public int RoleId { get; set; }

[Spalte (Reihenfolge = 0)] hinzugefügt, nachdem [Schlüssel] schrittweise um 1 hinzugefügt werden kann:

    [Key]
    [Column(Order = 1)]
    public int RoleIdName { get; set; }

etc...


Das hat den Trick für mich getan. Ich hatte [Schlüssel] bereits, aber das Hinzufügen der Bestellung löste es.
Jaitsujin

19

In meinem Fall wurde beim Erstellen eines "MVC 5-Controllers mit Ansicht unter Verwendung von Entity Framework" der Fehler angezeigt.

Ich musste das Projekt nur nach dem Erstellen der Model-Klasse erstellen und musste nicht die Annotation [Key] verwenden.


2
Ja - 'Als nächstes erstellen Sie das Projekt. Das Web-API-Gerüst verwendet Reflektion, um die Modellklassen zu finden, daher benötigt es die kompilierte Assembly. ' genommen von dieser Seite
Adam

Genau. Nur "Build" funktioniert und keine der anderen vorherigen Antworten! Ich habe viele Möglichkeiten ausprobiert und schließlich habe ich es gebaut und es hat funktioniert! Dann bin ich hierher gekommen und habe diese Antwort gefunden, die die richtige Antwort ist.
William Hou

großartig. Dies war mein Fall, nachdem Build alles gelöst ist
Alhpe

Ja .... DANKE .... Seltsam, dies ist ein Problem in einem neuen aktualisierten VS2019: D
JanBorup

11

Die Verwendung des [Schlüssels] hat bei mir nicht funktioniert, die Verwendung einer id-Eigenschaft jedoch. Ich füge diese Eigenschaft einfach meiner Klasse hinzu.

public int id {get; set;}

1
Es muss sein [Key], aber eine Eigenschaft namens " id" wird auch funktionieren.
Michael Blackburn

public int Id {get; einstellen; } oder [key] ^ public int Id1 {get; einstellen; }
Lava

6

Das Objekt muss ein Feld enthalten, das als verwendet Primary Keywird. Wenn Sie ein Feld mit dem Namen haben, Idist dies standardmäßig der Primärschlüssel des Objekts, mit dem Entity Framework verknüpft wird.

Andernfalls sollten Sie das [Key]Attribut über dem Feld hinzufügen, das Sie als verwenden möchten Primary Key, und Sie müssen auch den Namespace hinzufügen System.ComponentModel.DataAnnotations:

public class myClass
{
    public int Id { get; set; }
    [Key]
    public string Name { get; set; }
}

https://stackoverflow.com/a/51180941/7003760


Vielen Dank! Das Hinzufügen des Nuget-Pakets System.ComponentModel.Annotations zu unserem Unit Tests-Projekt hat diesen Fehler für mich behoben. Ich habe DbMigrator Update aufgerufen und es ist fehlgeschlagen, obwohl unser Domain-Projekt mit unseren Modellen und DbContext die Nuget-Referenz hatte. Beide Projekte brauchen es.
pwhe23

4

Denken Sie außerdem daran: Vergessen Sie nicht, ein solches öffentliches Schlüsselwort hinzuzufügen

[Key] 
int RoleId { get; set; } //wrong method

Sie müssen das öffentliche Schlüsselwort wie folgt verwenden

[Key] 
public int RoleId { get; set; } //correct method

2

Der Grund, warum das EF-Framework "kein Schlüssel" anfordert, ist, dass das EF-Framework einen Primärschlüssel in der Datenbank benötigt. Um EF deklarativ mitzuteilen, welche Eigenschaft der Schlüssel ist, fügen Sie eine [Key]Anmerkung hinzu. Oder fügen Sie am schnellsten eine IDEigenschaft hinzu. Dann wird das EF-Framework IDstandardmäßig als Primärschlüssel verwendet.


Was passiert, wenn in der Datenbank mehr als ein Feld mit der ID angegeben ist? Bei der Regeneration verliere ich das Schlüsselattribut.
Richard Griffiths

Wenn Sie den Code aus der Datenbank generieren, sollte eine der Spalten in der Tabelle der Primärschlüssel der Tabelle sein.
Michael Blackburn

Wenn Sie generierten Code "bearbeiten", wird er fast immer als partialKlasse generiert . Sie können eine zweite Datei als partialKlasse mit demselben Namen erstellen und die Eigenschaft mit dem [Key]Attribut erneut hinzufügen .
Michael Blackburn

1

Sie müssen nicht immer das Schlüsselattribut verwenden. Stellen Sie sicher, dass die Zuordnungsdatei den Schlüssel ordnungsgemäß adressiert hat

this.HasKey(t => t.Key);
this.ToTable("PacketHistory");
this.Property(p => p.Key)
            .HasColumnName("PacketHistorySK");

und vergessen Sie nicht, das Mapping im OnModelCreating des Repositorys hinzuzufügen

modelBuilder.Configurations.Add(new PacketHistoryMap());

1

Für mich war das Modell in Ordnung. Das lag daran, dass ich zwei verschiedene Versionen des Entity Frameworks hatte. Eine Version für das Webprojekt und eine andere für das gemeinsame Projekt, das die Modelle enthält.

Ich musste nur die Nuget-Pakete konsolidieren .

Geben Sie hier die Bildbeschreibung ein

Genießen!


Was meinst du mit "Konsolidieren der Nuget-Pakete"? Ich habe noch nie davon gehört ...
Rob Washington

0

Alles ist in Ordnung, aber in meinem Fall habe ich zwei Klassen wie diese

namespace WebAPI.Model
{
   public class ProductsModel
{ 
        [Table("products")]
        public class Products
        {
            [Key]
            public int slno { get; set; }

            public int productId { get; set; }
            public string ProductName { get; set; }

            public int Price { get; set; }
}
        }
    }

Nach dem Löschen der Oberschicht funktioniert es gut für mich.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.