EntityType n'a pas d'erreur de définition de clé

145

Manette:

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

    }
}

Modèle DbContext:

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

Modèle:

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

Table de base de données:

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

Dans global.asax.cs

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

Le code ci-dessus répertorie toutes les classes sur lesquelles je travaille. Lors de l'exécution de mon application, je reçois l'erreur:

"Une ou plusieurs erreurs de validation ont été détectées lors de la génération du modèle" ainsi que "Le type d'entité n'a pas de clé définie".

Codeur
la source
3
Vérifiez le fichier du référentiel. Toutes les solutions de cette page sont incroyables, mais dans mon cas, j'ai tout fait correctement, mais j'ai oublié de déclarer la table comme DbSet et de l'ajouter au modelbuilder.configurations.
Tosh
Dans mon cas, j'ai pointé le code vers une autre base de données et la table était absente de la base de données
Kristina Lex

Réponses:

168

La classe Model doit être remplacée par:

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; }
    }
}
Codeur
la source
1
mon code fonctionnait (sans [Key]) jusqu'à ce que je change les types de données (je les ai changés en unsigned) et seul l'octet fonctionne. Y a-t-il une raison pour laquelle je ne peux pas utiliser de unsignedvaleurs?
Mihai Bratulescu
5
Entity Framework ne prend pas en charge les entiers non signés msdn.microsoft.com/en-us/library/vstudio/…
user2316116
1
Et au cas où vous l'utilisez comme modèle dans MVC, n'oubliez pas de reconstruire!
RoJaIt
1
Beaucoup de choses différentes peuvent provoquer cette erreur. Dans mon cas, j'ai par erreur marqué mon champ "Id" "privé" au lieu de "public" (une habitude de Java / JPA). La réponse de Larry Raymond ci-dessous est sans doute la «meilleure» réponse à cette question. Il répertorie la plupart des scénarios courants derrière «EntityType n'a pas d'erreur définie par clé».
paulsm4
98
  1. Assurez-vous que les membres publics de la classe étudiante sont définis comme des propriétés avec {get; set;}(les vôtres sont des variables publiques - une erreur courante).

  2. Placez une [Key]annotation au-dessus de la propriété choisie.

Larry Raymond
la source
C'était mon problème. Merci. J'implémentais une interface qui ne nécessite qu'un getter pour l'ID
Henry Ing-Simmons
81

Cela peut se produire pour plusieurs raisons. J'ai trouvé certains d'entre eux ici , d'autres que j'ai découverts par moi-même.

  • Si la propriété est nommée autre chose que Id, vous devez lui ajouter l' [Key]attribut.
  • La clé doit être une propriété, pas un champ.
  • La clé doit être public
  • La clé doit être de type conforme CLS, ce qui signifie que les types non signés comme uint, ulongetc. ne sont pas autorisés.
  • Cette erreur peut également être causée par des erreurs de configuration .
BlueRaja - Danny Pflughoeft
la source
3
J'ai également constaté que la propriété clé doit être en lecture-écriture. J'ai eu l'erreur d'OP lorsque j'avais un getter et aucun setter sur la propriété ID.
JohnFx
1
@JohnFx est absolument correct. Resharper supprimé private setde certaines propriétés lors d'un nettoyage. Le résultat était le "EntityType n'a pas d'erreur définie par clé". Méfiez-vous donc des outils de nettoyage supprimant le code nécessaire.
jeremysawesome
Dans mon cas, j'ai utilisé un nom sans rapport pour mentionner l'identifiant de la classe. Changer cela comme mentionné dans votre solution a résolu mon problème. Thankyou :)
Angela Amarapala
Si vous utilisez une propriété comme ID, Id, ClassNameID, ClassNameIdvous ne devez pas devez utiliser[Key] attribute
Pranav Bilurkar
21

je sais que ce post est en retard mais cette solution m'a aidé:

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

ajouté [Column (Order = 0)] après [Key] peut être ajouté par incrément de 1:

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

etc...

Danigitman
la source
Cela a fait l'affaire pour moi. J'avais déjà [Key] mais l'ajout de l'ordre l'a résolu.
Jaitsujin le
19

Dans mon cas, j'obtenais l'erreur lors de la création d'un "MVC 5 Controller with view, using Entity Framework".

J'avais juste besoin de construire le projet après avoir créé la classe Model et je n'avais pas besoin d'utiliser l'annotation [Key].

ChrisS
la source
2
Oui - «Ensuite, construisez le projet. L'échafaudage de l'API Web utilise la réflexion pour trouver les classes de modèle, il a donc besoin de l'assembly compilé. ' extrait de cette page
Adam
Exactement. Seul "build" fonctionne, et aucune des autres réponses précédentes ne fonctionne! J'ai essayé de nombreuses façons et finalement je l'ai construit et cela a fonctionné! Puis je suis venu ici et j'ai trouvé cette réponse, qui est la bonne réponse.
William Hou
génial. c'était mon cas, après la construction, tout est résolu
alhpe
Oui .... MERCI .... Étrange, c'est un problème dans une nouvelle mise à jour VS2019: D
JanBorup
11

Utiliser la [key] ne fonctionnait pas pour moi mais utiliser une propriété id le fait. Je viens d'ajouter cette propriété dans ma classe.

public int id {get; set;}
William Bello
la source
1
Cela doit l'être [Key], mais une propriété appelée " id" fonctionnera également.
Michael Blackburn
public int Id {get; ensemble; } ou [clé] ^ public int Id1 {get; ensemble; }
lave le
6

L'objet doit contenir un champ qui sera utilisé comme Primary Key, si vous avez un champ nommé, Idce sera par défaut la clé primaire de l'objet vers lequel Entity Framework sera lié.

Sinon, vous devez ajouter l' [Key]attribut au-dessus du champ que vous souhaitez utiliser comme Primary Key, et vous devrez également ajouter l'espace de noms System.ComponentModel.DataAnnotations:

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

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

Mayer Spitzer
la source
Merci! L'ajout du package Nuget System.ComponentModel.Annotations à notre projet de tests unitaires a corrigé cette erreur pour moi. J'appelais DbMigrator Update et cela échouait même si notre projet de domaine avec nos modèles et DbContext avait la référence Nuget. Les deux projets en ont besoin.
pwhe23
4

N'oubliez pas non plus d'ajouter un mot clé public comme celui-ci

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

vous devez utiliser un mot clé public comme celui-ci

[Key] 
public int RoleId { get; set; } //correct method
Udara Kasun
la source
2

La raison pour laquelle le framework EF invite "no key" est que le framework EF a besoin d'une clé primaire dans la base de données. Pour indiquer de manière déclarative à EF la propriété de la clé, vous ajoutez une [Key]annotation. Ou, le moyen le plus rapide, ajoutez une IDpropriété. Ensuite, le framework EF prendra IDcomme clé primaire par défaut.

UtillYou
la source
Que se passe-t-il si la base de données a plus d'un champ suffixé avec ID? Lors de la régénération, je perds l'attribut Clé.
Richard Griffiths
Si vous générez le code à partir de la base de données, l'une des colonnes de la table doit être la clé primaire de la table.
Michael Blackburn
En ce qui concerne "l'édition" du code généré, il est presque toujours généré en tant que partialclasse. Vous pouvez créer un deuxième fichier en tant que partialclasse avec le même nom et ajouter à nouveau la propriété avec l' [Key]attribut.
Michael Blackburn
1

Vous n'êtes pas obligé d'utiliser l'attribut clé tout le temps. Assurez-vous que le fichier de mappage a correctement adressé la clé

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

et n'oubliez pas d'ajouter le mappage dans OnModelCreating du référentiel

modelBuilder.Configurations.Add(new PacketHistoryMap());
Tosh
la source
1

Pour moi, le modèle était bien. C'était parce que j'avais 2 versions différentes du framework d'entité. Une version pour le projet Web et une autre pour le projet commun qui contient les modèles.

Je devais juste consolider les paquets nuget .

entrez la description de l'image ici

Prendre plaisir!

Daniel
la source
Qu'entendez-vous par «consolider les paquets nuget»? Je n'ai jamais entendu parler de cela ....
Rob Washington
0

Tout va bien mais dans mon cas, j'ai deux classes comme celle-ci

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

Après avoir supprimé la classe supérieure, cela fonctionne très bien pour moi.

Debendra Dash
la source