EntityType no tiene error de clave definida

145

Controlador:

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

    }
}

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

Modelo:

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

Tabla de base de datos:

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

En global.asax.cs

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

El código anterior enumera todas las clases en las que estoy trabajando. Al ejecutar mi aplicación, recibo el error:

"Se detectaron uno o más errores de validación durante la generación del modelo" junto con "El tipo de entidad no tiene una clave definida".

Descifrador
fuente
3
Verifique el archivo del repositorio. Todas las soluciones en esta página son increíbles, pero en mi caso, hice todo bien, pero olvidé declarar la tabla como DbSet y agregarla a la configuración de modelbuilder.configurations.
Tosh
En mi caso, apunté el código a otra base de datos y faltaba la tabla de la base de datos
Kristina Lex

Respuestas:

168

La clase de modelo debe cambiarse a:

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; }
    }
}
Descifrador
fuente
1
mi código funcionó (sin [Key]) hasta que cambie los tipos de datos (los cambié a unsigned) y solo el byte funciona ¿hay alguna razón por la que no puedo usar unsignedvalores?
Mihai Bratulescu
55
Entity Framework no admite enteros sin firmar msdn.microsoft.com/en-us/library/vstudio/…
user2316116
1
Y en caso de que lo esté utilizando como modelo en MVC, ¡no olvide reconstruirlo!
RoJaIt
1
Muchas cosas diferentes pueden causar este error. En mi caso, marqué mi campo "Id" por error "privado" en lugar de "público" (un hábito de Java / JPA). La respuesta de Larry Raymond a continuación es posiblemente la "mejor" respuesta a esta pregunta. Enumera la mayoría de los escenarios comunes detrás de "EntityType no tiene ningún error definido de clave".
paulsm4
98
  1. Asegúrese de que los miembros públicos de la clase de estudiantes estén definidos como propiedades w / {get; set;}(las suyas son variables públicas , un error común).

  2. Coloque una [Key]anotación en la parte superior de su propiedad elegida.

Larry Raymond
fuente
Este fue mi problema. Gracias. Estaba implementando una interfaz que solo requiere un captador para la identificación
Henry Ing-Simmons
81

Hay varias razones por las que esto puede suceder. Algunos de estos los encontré aquí , otros los descubrí por mi cuenta.

  • Si la propiedad recibe un nombre diferente Id, debe agregarle el [Key]atributo.
  • La clave debe ser una propiedad, no un campo.
  • La clave debe ser public
  • La clave debe ser un tipo compatible con CLS, lo que significa que no se permiten tipos sin signo como uint, ulongetc.
  • Este error también puede ser causado por errores de configuración .
BlueRaja - Danny Pflughoeft
fuente
3
También he encontrado que la propiedad clave tiene que ser de lectura-escritura. Obtuve el error de OP cuando tenía un getter y ningún setter en la propiedad ID.
JohnFx
1
@JohnFx es absolutamente correcto. Resharper eliminado private setde algunas propiedades durante una limpieza. El resultado fue el "EntityType no tiene error definido clave". Así que tenga cuidado con las herramientas de limpieza que eliminan el código necesario.
jeremysawesome
En mi caso, usé un nombre no relacionado para mencionar el Id de la clase. Cambiar eso como se menciona en su solución resolvió mi problema. Gracias :)
Angela Amarapala
Si se utiliza cualquier propiedad como ID, Id, ClassNameID, ClassNameIdno es necesario tener que utilizar[Key] attribute
Pranav Bilurkar
21

Sé que esta publicación llega tarde, pero esta solución me ayudó:

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

se agregó [Columna (Orden = 0)] después de que [Clave] se puede agregar incrementando en 1:

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

etc ...

danigitman
fuente
Esto hizo el truco para mí. Ya tenía [Key] pero al agregar el orden lo resolvió.
Jaitsujin
19

En mi caso, recibí el error al crear un "Controlador MVC 5 con vista, usando Entity Framework".

Solo necesitaba construir el proyecto después de crear la clase Modelo y no necesitaba usar la anotación [Clave].

ChrisS
fuente
2
Sí - 'Luego, construye el proyecto. El andamio de API web utiliza la reflexión para encontrar las clases de modelo, por lo que necesita el ensamblado compilado '. tomado de esta página
Adam
Exactamente. ¡Solo "construir" funciona, y ninguna de las otras respuestas anteriores funciona! Lo intenté de muchas maneras y finalmente lo construí y funcionó. Luego vine aquí y encontré esta respuesta, que es la respuesta correcta.
William Hou
Excelente. Este fue mi caso, después de que todo se resuelve
alhpe
Sí ... GRACIAS ... Extraño, este es un problema en un nuevo VS2019 actualizado: D
JanBorup
11

Usar la [clave] no funcionó para mí, pero usar una propiedad de identificación lo hace. Acabo de agregar esta propiedad en mi clase.

public int id {get; set;}
William Bello
fuente
1
Tiene que serlo [Key], pero una propiedad llamada " id" también funcionará.
Michael Blackburn
Id público int {get; conjunto; } o [clave] ^ public int Id1 {get; conjunto; }
lava
6

El objeto debe contener un campo que se utilizará como Primary Key, si tiene un campo con nombre Id, esta será, por defecto, la clave principal del objeto al que se vinculará Entity Framework.

De lo contrario, debe agregar el [Key]atributo sobre el campo que desea usar como Primary Key, y también deberá agregar el espacio de nombres 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
fuente
¡Gracias! Agregar el paquete System.ComponentModel.Annotations Nuget a nuestro proyecto de Pruebas unitarias solucionó este error. Estaba llamando a DbMigrator Update y estaba fallando a pesar de que nuestro proyecto de Dominio con nuestros modelos y DbContext tenía la referencia Nuget. Ambos proyectos lo necesitan.
pwhe23
4

Además, recuerde, no olvide agregar palabras clave públicas como esta

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

debes usar una palabra clave pública como esta

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

La razón por la cual el marco de trabajo de EF pide 'sin clave' es que el marco de EF necesita una clave primaria en la base de datos. Para decirle a EF de forma declarativa qué propiedad es la clave, agregue una [Key]anotación. O, de la manera más rápida, agregue una IDpropiedad. Entonces, el marco EF tomará IDcomo clave principal por defecto.

UtillYou
fuente
¿Qué sucede si la base de datos tiene más de un campo con el sufijo ID? En la regeneración pierdo el atributo clave.
Richard Griffiths
Si está generando el código de la base de datos, una de las columnas de la tabla debe ser la clave principal de la tabla.
Michael Blackburn
En cuanto a la "edición" del código generado, casi siempre se genera como una partialclase. Puede crear un segundo archivo como partialclase con el mismo nombre y agregar la propiedad nuevamente con el [Key]atributo.
Michael Blackburn
1

No tiene que usar el atributo clave todo el tiempo. Asegúrese de que el archivo de mapeo haya abordado correctamente la clave

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

y no olvides agregar el mapeo en OnModelCreating del Repositorio

modelBuilder.Configurations.Add(new PacketHistoryMap());
Tosh
fuente
1

Para mí, el modelo estaba bien. Fue porque tenía 2 versiones diferentes del marco de la entidad. Una versión para el proyecto web y otra para el proyecto común que contiene los modelos.

Solo tuve que consolidar los paquetes nuget .

ingrese la descripción de la imagen aquí

¡Disfrutar!

Daniel
fuente
¿Qué quiere decir con "consolidar los paquetes nuget"? Nunca he oído hablar de esto ...
Rob Washington
0

Todo está bien, pero en mi caso tengo dos clases como esta

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

Después de eliminar la clase alta, funciona bien para mí.

Debendra Dash
fuente