【问题标题】:Why EF Core 5 does not create "Primary Key Autoincrement" using "[Key]" attribute on "Id" property of my entity "Address"?为什么 EF Core 5 不使用我的实体“地址”的“Id”属性上的“[Key]”属性创建“主键自动增量”?
【发布时间】:2021-02-21 06:19:27
【问题描述】:

我在我的 VS 2019 项目中使用 Microsoft.EntityFrameworkCore v5.0.3(在 .NET Core 3.1 上运行)。

正如您在实体类Address 中看到的,第一个属性int Id 具有属性[Key]

[Index(nameof(Country))]
[Index(nameof(ZIP))]
[Index(nameof(City))]
public class Address
{
    [Key]
    public int Id { get; set; }

    [Timestamp]
    public byte[] RowVersion { get; set; }

    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime ChangedAt { get; set; } = DateTime.UtcNow;

    [StringLength(EFConst.MAX_LEN_COUNTRY)]
    public string Country { get; set; }     
    
    [StringLength(EFConst.MAX_LEN_ZIP)]
    public string ZIP { get; set; }
    
    [StringLength(EFConst.MAX_LEN_CITY)]
    public string City { get; set; }

    [StringLength(EFConst.MAX_LEN_STREET)]
    public string Street { get; set; }
}

但在创建数据库架构后,我在使用 Microsoft SQL Server Management Studio 的 CREATE TABLE 脚本中既看不到 PRIMARY KEY 也看不到 AUTOINCREMENT,如您在此处看到的:

CREATE TABLE [dbo].[Addresses]
(
    [ID] [int] NOT NULL,
    [RowVersion] [timestamp] NOT NULL,
    [CreatedAt] [datetime] NOT NULL,
    [ChangedAt] [datetime] NOT NULL,
    [Country] [nvarchar](64) NULL,
    [ZIP] [nvarchar](32) NULL,
    [City] [nvarchar](64) NULL,
    [Street] [nvarchar](128) NULL,

    CONSTRAINT [PK_dbo.Addresses] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
                WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                      IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                      ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

现在,当这段代码被执行时:

var addr1 = db.Addresses.Add(new Address
{
    Country = "SampleCountry",
    City = "SampleCity",
    ZIP = "12345",
    Street = "SampleStreet 123"
});

db.SaveChanges();

我在db.SaveChanges() 收到此异常:

Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。详情见内部异常

内部异常

SqlException:无法将值 NULL 插入列“ID”、表“NSA.dbo.Addresses”;列不允许空值。插入失败。声明已终止。

我不知道为什么会抛出异常。

为什么表Addresses中的列ID没有定义为PRIMARY AUTOINCREMENT

我已经搜索/谷歌了整个互联网......并到达了它的边界。

solutions on Stackoverflow(或其他地方)都不适合我! 正如official documentation of EF Core 中所述,我的简单项目应该可以工作!

我已经在以下实验(单个和一些组合)进行了逐步尝试和错误,但没有成功:

  • 使用“数据注释”(属性):
    • [Key]
    • [Required]
    • [Required, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    • [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  • Id 重命名为AddressId(+ 以上使用属性的组合)
  • 通过覆盖 void OnModelCreating(...) 和使用 modelBuilder.Entity<Address>().HasKey(a => a.Id); 来使用 Fluent API
  • 将属性 Id 重新定义为:int? Idint IDint? IDint AddressIdint? AddressIdint AddressIDint? AddressID

我做错了吗?

如何使用 EF Core 将“Address”类的“Id”属性定义为 PRIMARY KEY + AUTOINCREMENT?

谢谢!

【问题讨论】:

  • 您在后端使用什么数据库?例如 SQL Server 没有有一个 AUTOINCREMENT 关键字 - 它被称为 IDENTITY
  • @marc_s 我正在使用 SQL EXPRESS (MSSQL 15)。 SQL创建脚本中也没有“IDENTITY”关键字!
  • 您在使用此注释后是否进行了另一次迁移和数据库更新? [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  • @MohamedAdel 你是对的!问题是我在重新创建数据库之前没有删除它(facepalm)。非常感谢您的帮助并挽救了我的一天。
  • @user14867525 不客气,我已添加为答案,请接受以供进一步需求

标签: .net-core entity-framework-core sqlexception


【解决方案1】:

您在使用此注解后是否进行了另一次迁移和数据库更新?

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

您只需要进行另一次迁移并更新您的数据库

【讨论】:

  • 这应该没有必要。文档说:“按照惯例,名为 Id 或 Id 的属性将被配置为实体的主键。”
【解决方案2】:

感谢@MohamedAdel,我解决了删除数据库并重新创建它的问题。现在“ID”列定义为

[Id] [int] IDENTITY(1,1) NOT NULL

一切都很好。 谢谢大家的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多