EntityType não possui erro definido por chave


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

Tabela do banco de dados:

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

Em global.asax.cs

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

O código acima lista todas as classes nas quais estou trabalhando. Ao executar meu aplicativo, estou recebendo o erro:

"Um ou mais erros de validação foram detectados durante a geração do modelo", juntamente com "O tipo de entidade não possui uma chave definida".


3
Verifique o arquivo do repositório. Todas as soluções nesta página são incríveis, mas, no meu caso, fiz tudo certo, mas esqueci de declarar a tabela como DbSet e adicioná-la às modelbuilder.configurations.
Tosh

No meu caso, eu apontei o código para outro db ea mesa estava faltando db
Kristina Lex

Respostas:


168

A classe Model deve ser alterada para:

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
meu código funcionou (sem [Key]) até que eu altere os tipos de dados (eu os alterei para unsigned) e apenas o byte funciona existe um motivo pelo qual não posso usar unsignedvalores?
Mihai Bratulescu

5
O Entity Framework não oferece suporte a números inteiros não assinados msdn.microsoft.com/en-us/library/vstudio/…
user2316116

1
E caso você esteja usando-o como modelo no MVC, não se esqueça de reconstruir!
RoJaIt

1
Muitas coisas diferentes podem causar esse erro. No meu caso, marquei por engano o meu campo "Id" como "privado" em vez de "público" (um hábito de Java / JPA). A resposta de Larry Raymond abaixo é sem dúvida a "melhor" resposta a essa pergunta. Ele lista a maioria dos cenários comuns por trás de "EntityType não possui erro definido por chave".
paulsm4

98
  1. Certifique-se de que os membros públicos da turma sejam definidos como propriedades com {get; set;}(as suas são variáveis públicas - um erro comum).

  2. Coloque uma [Key]anotação em cima da propriedade escolhida.


Este foi o meu problema. Obrigado. Eu estava implementação de uma interface que requer apenas um getter para ID
Henry Ing-Simmons

81

Existem várias razões pelas quais isso pode acontecer. Alguns deles eu encontrei aqui , outros eu descobri por conta própria.

  • Se a propriedade tiver um nome diferente de Id, você precisará adicionar o [Key]atributo a ela.
  • A chave precisa ser uma propriedade, não um campo.
  • A chave precisa ser public
  • As principais necessidades para ser um tipo compatíveis com CLS, ou seja, os tipos não assinados gosto uint, ulongetc. não são permitidos.
  • Este erro também pode ser causado por erros de configuração .

3
Também descobri que a propriedade key deve ser de leitura e gravação. Eu recebi o erro do OP quando tinha um getter e nenhum setter na propriedade ID.
JohnFx

1
@JohnFx está absolutamente correto. Recarregador removido private setde algumas propriedades durante uma limpeza. O resultado foi o "EntityType não possui erro definido por chave". Portanto, cuidado com as ferramentas de limpeza, removendo o código necessário.
21417 jeremysawesome #

No meu caso, usei um nome não relacionado para mencionar o ID da classe. Mudar isso como mencionado na sua solução resolveu meu problema. Obrigado :)
Angela Amarapala

Se você usar qualquer propriedade como ID, Id, ClassNameID, ClassNameIdvocê não precisa ter que usar[Key] attribute
Pranav Bilurkar

21

Eu sei que este post está atrasado, mas esta solução me ajudou:

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

[Coluna (Order = 0)] adicionada depois que [Key] pode ser adicionada por incremento de 1:

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

etc ...


Isso fez o truque para mim. Eu já tinha [Key], mas a adição do pedido foi resolvida.
Jaitsujin 28/02

19

No meu caso, eu estava recebendo o erro ao criar um "MVC 5 Controller com vista, usando o Entity Framework".

Eu só precisava criar o projeto depois de criar a classe Model e não precisei usar a anotação [Key].


2
Sim - 'Em seguida, construa o projeto. O andaime da API da Web usa reflexão para encontrar as classes de modelo, portanto, ele precisa do assembly compilado. ' retirado desta página
Adam

Exatamente. Somente "build" funciona, e nenhuma das outras respostas anteriores funciona! Eu tentei de várias maneiras e finalmente eu o construí e funcionou! Então eu vim aqui e encontrei esta resposta, que é a resposta correta.
William Hou

ótimo. este foi o meu caso, depois de construir tudo fica resolvido
alhpe

Sim .... OBRIGADO .... Estranho, este é um problema em um novo VS2019 atualizado: D
JanBorup 25/02

11

Usar a [chave] não funcionou para mim, mas usar uma propriedade id funciona. Acabei de adicionar esta propriedade na minha classe.

public int id {get; set;}

1
Precisa ser [Key], mas uma propriedade chamada " id" também funcionará.
Michael Blackburn

public int Id {get; conjunto; } ou [chave] ^ public int Id1 {get; conjunto; }
lava

6

O objeto deve conter um campo que será usado como o Primary Key, se você tiver um campo chamadoId , essa será, por padrão, a chave primária do objeto ao qual o Entity Framework se vinculará.

Caso contrário, você deve adicionar o [Key]atributo acima desse campo que deseja usar como o Primary Keye também precisará adicionar o espaço para nome System.ComponentModel.DataAnnotations:

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

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


Obrigado! A adição do pacote System.ComponentModel.Annotations Nuget ao nosso projeto Unit Tests corrigiu esse erro para mim. Eu estava ligando para o DbMigrator Update e estava falhando, embora nosso projeto de domínio com nossos modelos e o DbContext tivesse a referência Nuget. Ambos os projetos precisam.
pwhe23

4

Além disso, lembre-se, não se esqueça de adicionar palavras-chave públicas como esta

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

você deve usar a palavra-chave pública como esta

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

2

A razão pela qual a estrutura EF solicita 'sem chave' é que a estrutura EF precisa de uma chave primária no banco de dados. Para informar declarativamente à EF qual propriedade é a chave, adicione uma [Key]anotação. Ou, da maneira mais rápida, adicione uma IDpropriedade. Em seguida, a estrutura EF terá IDcomo chave primária por padrão.


O que acontece se o banco de dados tiver mais de um campo com o sufixo ID? Na regeneração, perco o atributo Key.
Richard Griffiths

Se você estiver gerando o código a partir do banco de dados, uma das colunas da tabela deve ser a chave principal da tabela.
Michael Blackburn

Em relação à "edição" do código gerado, ele quase sempre é gerado como uma partialclasse. Você pode criar um segundo arquivo como uma partialclasse com o mesmo nome e adicionar a propriedade novamente com o [Key]atributo
Michael Blackburn

1

Você não precisa usar o atributo-chave o tempo todo. Verifique se o arquivo de mapeamento endereçou corretamente a chave

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

e não se esqueça de adicionar o mapeamento no OnModelCreating do Repositório

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

1

Para mim, o modelo estava bem. Foi porque eu tinha duas versões diferentes da estrutura da entidade. Uma versão para o projeto da web e outra para o projeto comum que contém os modelos.

Eu apenas tive que consolidar os pacotes de pepitas .

insira a descrição da imagem aqui

Aproveitar!


O que você quer dizer com "consolidar os pacotes nuget"? Eu nunca ouvi falar deste ....
Rob Washington

0

Tudo está certo, mas no meu caso eu tenho duas classes 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; }
}
        }
    }

Depois de excluir a classe alta, funciona bem para mim.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.