【问题标题】:"Cannot insert explicit value for identity column in table" when inserting object with EF Core使用 EF Core 插入对象时,“无法为表中的标识列插入显式值”
【发布时间】:2020-02-03 03:38:37
【问题描述】:

我正在尝试使用 EF Core、SQL Server 和 C# 在我的表中插入一个新行,但我无法让 EF Core 正确使用标识列。

这是我正在做的事情:

我正在使用 Entity Framework 生成的类创建一个新对象(我在帖子末尾包含了实体类定义)

EmployeePermissions employee_permission = new EmployeePermissions
{
    FkEmployee = PkEmployee,
    FkPermission = permission_key
};

然后我调用db.EmployeePermissions.add(employee_permission),它适用于对象来自[FromBody] <Entity Class> <object_variable> 的所有调用(尽管使用其他表)。

但是在这里,当我自己实例化这个类时,我得到了这个错误:

SqlException (0x80131904):当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Employee_Permissions”中插入标识列的显式值。

我不明白为什么会这样——我希望它自动增加标识列。我使用ObjectDumper 来查看传递给.Add() 的内容,如下:

properties {
    PkEmployeePermissions = 0 [System.Int32] // this is the identity column, of course
    FkEmployee = 31 [System.Int32]
    FkPermission = 6 [System.Int32]
    FkEmployeeNavigation = <null>
    FkPermissionNavigation = <null>
}

我已经调查了其他运行良好的调用([FromBody] 创建对象的调用)并且标识列在这些调用中也简单地等于0,所以我不明白这里有什么不同。

我是否错误地配置了数据库中的某些内容?我在列属性中仔细检查了PkEmployeePermissions 列确实是一个标识列,所以它应该自动递增。

如果有帮助,这里是 Entity 类:

public partial class EmployeePermissions
{
    public int PkEmployeePermissions { get; set; }
    public int FkEmployee { get; set; }
    public int FkPermission { get; set; }

    public Employee FkEmployeeNavigation { get; set; }
    public Permission FkPermissionNavigation { get; set; }
}

【问题讨论】:

  • @AbdullahDibas 这确实是解决方案!我需要重新生成数据库脚手架。在我将主键设置为身份列之后,我一定忘记了这样做。
  • 经过进一步调查,确切的问题是该列在 EF Core 数据库上下文文件中的 modelBuilder 内设置了 .ValueGeneratedNever()。我会将其添加到实际答案中,因此它不是另一个问题的直接重复,而是提供一些适当的上下文,说明这在 EF Core 中是如何发生的。

标签: c# sql-server entity-framework entity-framework-core


【解决方案1】:

原来我已将主键列 PkEmployeePermission 更新为标识列,却忘记使用 EF Core 重新生成数据库脚手架。

问题的根本原因是在OnModelCreating() 方法内部(在生成的数据库上下文文件中)字段PkEmployeePermission 调用了.ValueGeneratedNever() 方法,这意味着即使它是主要的键,EF Core 不会自动为该列生成递增值。通过在数据库上下文文件中注释掉该方法,代码可以正常工作。

【讨论】:

    【解决方案2】:

    默认约定是将类的主键称为 Id(classname)Id - 在您的类中并非如此。

    另外:如果您要映射到 SQL Server 中的 IDENTITY 列,则必须向键列添加相关数据注释。

    试试这个:

    public partial class EmployeePermissions
    {
        // add the [Key] annotation to indicate the primary key of the class/table
        [Key]
        // add the [DatabaseGenerated(..)] annotation to indicate an IDENTITY column in the table
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int PkEmployeePermissions { get; set; }
        public int FkEmployee { get; set; }
        public int FkPermission { get; set; }
    
        public Employee FkEmployeeNavigation { get; set; }
        public Permission FkPermissionNavigation { get; set; }
    }
    

    现在您应该能够插入这些对象,并将它们正确存储在您的 SQL Server 表中。

    【讨论】:

    • EF 生成的脚手架都没有任何注释,如果我添加该代码,它不会解析到任何包。我正在使用 EF Core,您使用的是 EF 6 还是类似的东西?我了解标识列的命名约定,但我继承了这个项目,并且该格式已经存在并且在数据库中的其他 30 个奇数表上工作正常。
    猜你喜欢
    • 1970-01-01
    • 2019-05-28
    • 2017-12-31
    • 2021-07-02
    • 2016-04-13
    • 2015-10-27
    • 2020-03-09
    相关资源
    最近更新 更多