EntityType没有键定义错误


145

控制器:

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模型:

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

模型:

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

数据库表:

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

在global.asax.cs中

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

上面的代码列出了我正在处理的所有类。在运行我的应用程序时收到错误:

“在模型生成期间检测到一个或多个验证错误”以及“实体类型未定义键”。


3
检查存储库文件。该页面上的所有解决方案都很了不起,但就我而言,我做了所有正确的事情,但是忘记将表声明为DbSet并将其添加到modelbuilder.configurations中。
Tosh 2015年

就我而言,我将代码指向另一个数据库,而该数据库中没有该表
Kristina Lex

Answers:


168

Model类应更改为:

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
[Key]更改数据类型(将它们更改为)之前,我的代码一直有效(没有),unsigned并且只有字节有效,这是我不能使用unsigned值的原因吗?
Mihai Bratulescu 2014年

5
实体框架不支持无符号整数msdn.microsoft.com/en-us/library/vstudio/...
user2316116

1
而且,如果您将其用作MVC中的模型,请不要忘记进行重建!
RoJaIt '18

1
许多不同的事情都可能导致此错误。就我而言,我错误地将“ Id”字段标记为“ private”,而不是“ public”(Java / JPA的习惯)。拉里·雷蒙德(Larry Raymond)在下面的回答可以说是对该问题的“最佳”答复。它列出了“ EntityType没有密钥定义的错误”后面的大多数常见情况。
paulsm4

98
  1. 确保将学生班级的公共成员定义为带有w的属性{get; set;}(您是公共变量,这是一个常见错误)。

  2. [Key]在所选属性的顶部放置一个注释。


这是我的问题。谢谢。我正在实现一个只需要ID吸气剂的接口
Henry Ing-Simmons,

81

发生这种情况有多种原因。我在这里找到其中一些,其他是我自己发现的。

  • 如果该属性的名称不是Id,则需要为其添加[Key]属性。
  • 密钥必须是属性,而不是字段。
  • 关键是 public
  • 关键的需求是一个符合CLS的类型,这意味着无符号类型一样uintulong等都是不允许的。
  • 此错误也可能是由配置错误引起的。

3
我还发现key属性必须是可读写的。当我在ID属性上有一个getter而没有setter时,出现OP的错误。
JohnFx

1
@JohnFx是绝对正确的。private set清理过程中从某些属性中移除了Resharper 。结果是“ EntityType没有密钥定义错误”。因此请当心清理工具,删除必要的代码。
jeremysawesome

就我而言,我使用了一些无关的名称来提及该类的ID。如您的解决方案中所述更改它可以解决我的问题。谢谢:)
安吉拉·阿马拉帕拉

如果你使用像任何财产IDIdClassNameIDClassNameId你不必为使用[Key] attribute
Pranav Bilurkar

21

我知道这篇文章很晚,但是此解决方案帮助了我:

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

[Key]之后添加的[Column(Order = 0)]可以按1递增:

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

等等...


这对我有用。我已经有了[Key],但是添加命令解决了它。
斋藤

19

就我而言,在创建“使用实体框架的带有视图的MVC 5控制器”时出现错误。

我只需要在创建Model类之后就构建项目,并且不需要使用[Key]批注。


2
是的-'下一步,构建项目。Web API支架使用反射来查找模型类,因此需要编译的程序集。摘自本页
亚当

究竟。只有“ build”有效,其他先前的答案都无效!我尝试了很多方法,最后我建立了它,并且成功了!然后我来到这里,找到了这个答案,这是正确的答案。
侯厚

大。这是我的情况,所有构建都解决后
alhpe19年

是的....谢谢....奇怪的是,这是新更新的VS2019中的一个问题:D
JanBorup

11

使用[key]对我不起作用,但是使用id属性可以。我只是在课程中添加此属性。

public int id {get; set;}

1
它必须为[Key],但id也可以使用名为“ ” 的属性。
迈克尔·布莱克本

public int ID {get; 组; }或[key] ^ public int Id1 {get; 组; }
熔岩

6

该对象必须包含一个用作的字段Primary Key,如果您有一个名为的字段,Id则默认情况下,这将是Entity Framework链接至的对象的主键。

否则,您应该在[Key]要用作的字段上方添加属性Primary Key,并且还需要添加名称空间System.ComponentModel.DataAnnotations

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

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


谢谢!将System.ComponentModel.Annotations Nuget包添加到我们的单元测试项目中,为我解决了此错误。我正在调用DbMigrator Update,但即使我们的带有模型和DbContext的Domain项目具有Nuget参考,它也失败了。两个项目都需要它。
pwhe23

4

另外请记住,别忘了添加这样的公共关键字

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

您必须像这样使用Public关键字

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

2

EF框架提示“无键”的原因是EF框架需要数据库中的主键。要以声明方式告诉EF密钥是哪个属性,请添加[Key]注释。或者,以最快的方式添加ID属性。然后,ID默认情况下,EF框架将作为主键。


如果数据库有多个带有ID后缀的字段,会发生什么情况?再生时,我失去了Key属性。
理查德·格里菲思

如果要从数据库生成代码,则表中的列之一应该是表的主键。
迈克尔·布莱克本

关于“编辑”生成的代码,几乎总是将其作为一个partial类生成。您可以将第二个文件创建为partial具有相同名称的类,然后使用属性再次添加[Key]属性。
迈克尔·布莱克本

1

您不必一直使用key属性。确保映射文件正确解决了密钥

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

并且不要忘记在存储库的OnModelCreating中添加映射

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

1

对我来说,模型很好。因为我有两个不同的版本的实体框架。Web项目的一个版本,而包含模型的公共项目的另一个版本。

我只需要合并nuget软件包即可

在此处输入图片说明

请享用!


您“巩固nuget包”是什么意思?我从来没有听说过这个....
罗布华盛顿

0

没事,但就我而言,我有两个这样的班级

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

删除上层阶级后,对我来说效果很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.