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


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

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.


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 .

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


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


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

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


¡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

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.


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

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!


¿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í.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.