【问题标题】:EntityType has no key defined errorEntityType 没有键定义错误
【发布时间】:2013-11-25 21:16:23
【问题描述】:

控制器:

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

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

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

【问题讨论】:

  • 检查存储库文件。此页面中的所有解决方案都很棒,但就我而言,我做的一切都是正确的,但忘记将表声明为 DbSet 并将其添加到 modelbuilder.configurations。
  • 在我的情况下,我将代码指向另一个数据库,而数据库中缺少该表

标签: c# .net entity-framework


【解决方案1】:

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

【讨论】:

  • 我的代码工作(没有[Key]),直到我更改数据类型(我将它们更改为unsigned)并且只有字节工作是有原因我不能使用unsigned 值吗?
  • 实体框架不支持无符号整数msdn.microsoft.com/en-us/library/vstudio/…
  • 如果你将它用作 MVC 中的模型,别忘了重建!
  • 许多不同的事情都可能导致此错误。就我而言,我错误地将我的“Id”字段标记为“private”而不是“public”(Java/JPA 的一种习惯)。拉里·雷蒙德(Larry Raymond)的response 可以说是对这个问题的“最佳”回答。它列出了“EntityType has no key defined error”背后的大部分常见场景。
【解决方案2】:

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

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

【讨论】:

  • 我还发现 key 属性必须是可读写的。当我在 ID 属性上有一个 getter 而没有 setter 时,我得到了 OP 的错误。
  • @JohnFx 是绝对正确的。 Resharper 在清理期间从某些属性中删除了 private set。结果是“EntityType has no key defined error”。所以要小心清理工具删除必要的代码。
  • 就我而言,我使用了一些不相关的名称来提及班级的 Id。如您的解决方案中所述更改它解决了我的问题。谢谢你:)
  • 如果你使用IDIdClassNameIDClassNameId等任何属性,则不必使用[Key] attribute
  • 完全随机,但是当它发生在我身上时,是因为我的 DataContext 类引用了错误的类。例如公共 DbSet 付款 { 获取;放; }
【解决方案3】:
  1. 确保学生类的公共成员被定义为 properties w/{get; set;}(你的是公共变量 - 一个常见错误)。

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

【讨论】:

  • 这是我的问题。谢谢。我正在实现一个只需要一个获取 ID 的接口
【解决方案4】:

在我的例子中,我在创建“MVC 5 Controller with view, using Entity Framework”时遇到了错误。

我只需要在创建Model类后构建项目,不需要使用[Key]注解。

【讨论】:

  • Yes - '接下来,构建项目。 Web API 脚手架使用反射来查找模型类,因此它需要已编译的程序集。取自this page
  • 没错。只有“构建”有效,其他以前的答案都没有!我尝试了很多方法,最后我构建了它并且它成功了!然后我来到这里,找到了这个答案,就是正确答案。
  • 太棒了。这是我的情况,构建后一切都得到解决
  • 是的....谢谢....奇怪的是,这是新更新的 VS2019 中的一个问题:D
【解决方案5】:

我知道这篇文章迟到了,但是 这个解决方案帮助了我:

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

添加了 [Column(Order = 0)] [关键]之后 可以加1:

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

等等……

【讨论】:

  • 这对我有用。我已经有 [Key] 但添加订单解决了它。
【解决方案6】:

另外记住,不要忘记像这样添加 public 关键字

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

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

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

【讨论】:

  • 这为我指明了正确的方向,我将它作为一个字段(没有声明 get/set)。更改为属性,一切都很好。谢谢
【解决方案7】:

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

否则,您应该在要用作Primary Key 的字段上方添加[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 更新,即使我们的域项目与我们的模型和 DbContext 有 Nuget 参考,它也失败了。 两个项目都需要它。
【解决方案8】:

使用 [key] 对我不起作用,但使用 id 属性可以。 我只是在我的类中添加了这个属性。

public int id {get; set;}

【讨论】:

  • 它必须是[Key],但一个名为“id”的属性也可以。
  • public int Id { get;放; } 或 [key] ^ public int Id1 { get;放; }
【解决方案9】:

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

我只需要整合 nuget 包

享受吧!

【讨论】:

  • “整合 nuget 包”是什么意思?我从来没有听说过这个....
【解决方案10】:

EF框架提示'no key'的原因是EF框架需要数据库中的主键。要以声明方式告诉 EF 密钥是哪个属性,请添加 [Key] 注释。或者,最快的方法是添加一个ID 属性。那么EF框架默认会以ID为主键。

【讨论】:

  • 如果数据库有多个以ID为后缀的字段会怎样?重新生成时,我失去了 Key 属性。
  • 如果您从数据库生成代码,表中的列之一应该是表的主键。
  • 关于“编辑”生成的代码,它几乎总是生成为partial 类。您可以将第二个文件创建为具有相同名称的partial 类,然后使用[Key] 属性再次添加该属性。
【解决方案11】:

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

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

别忘了在 Repository 的 OnModelCreating 中添加映射

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

【讨论】:

    【解决方案12】:

    一切正常,但就我而言,我有两个这样的班级

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

    删除上层后它对我来说很好。

    【讨论】:

      【解决方案13】:

      我也在我自己的项目中通过解决我的代码中的这一特定行来解决这个问题。 我添加了以下内容。

      [DatabaseGenerated(DatabaseGeneratedOption.None)]
      

      意识到自己的错误后,我就去把它改成了

      [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      

      这进一步确保了每次在数据库中插入新行时名为“Id”的字段的值会增加

      【讨论】:

        猜你喜欢
        • 2017-02-19
        • 1970-01-01
        • 1970-01-01
        • 2015-12-11
        • 2016-04-02
        • 2016-03-16
        • 2013-08-04
        • 2012-12-10
        相关资源
        最近更新 更多