数据库中的代码优先 - 无法将值 NULL 插入列 'Id' 但值实际上不为空

Code first from Database - Cannot insert the value NULL into column 'Id' but value actually is not null

我尝试添加新记录:

                 entity.Id = Id;


                _bdc.EquifaxAnswers.Add(entity);

                _bdc.SaveChanges();

并且 Id 已准确定义为主键并且代码中的 Id 具有值(对于 table 是唯一的)。 并且 EF 创建 sql 添加记录的代码:

 INSERT [dbo].[EquifaxAnswers]([FileName], [dtSend], [dtDateTime], [RecordsAll], [RecordsCorrect], 
[RecordsIncorrect], [ResendedId], [dtEmailAbout], [StartDate], [EndDate])
VALUES (@0, @1, @2, NULL, NULL, NULL, NULL, NULL, @3, @4)

正如我们所见,Id 不存在,因此 _bdc.SaveChanges();创建异常:

Failed in 25 ms with error: Cannot insert the value NULL into column 'Id', table 'Equifax.dbo.EquifaxAnswers'; column does not allow nulls. INSERT fails.

主键定义:

    public partial class EquifaxAnswers
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

为什么 EF 不添加 Id 到 INSERT 以及如何解决这个问题?

更新: Table 数据库中的定义脚本:

CREATE TABLE [dbo].[EquifaxAnswers](
[Id] [int] NOT NULL,
[FileName] [nvarchar](300) NOT NULL,
[dtSend] [datetime] NOT NULL,
[dtDateTime] [datetime] NULL,
[RecordsAll] [int] NULL,
[RecordsCorrect] [int] NULL,
[RecordsIncorrect] [int] NULL,
[ResendedId] [int] NULL,
[dtEmailAbout] [datetime] NULL,
[StartDate] [datetime] NULL,
[EndDate] [datetime] NULL,
CONSTRAINT [PK_EquifaxAnswers] PRIMARY KEY CLUSTERED 
(
[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

您已指定 DatabaseGeneratedOption.None

这意味着 EF 不希望数据库生成 Id 字段,您应该自己指定 Id 字段。

如果希望数据库自动生成Id字段,则将列修改为IDENTITY类型,并将代码修改为DatabaseGeneratedOption.Identity

解法:

            modelBuilder.Entity<EquifaxAnswers>()
            .Property(a => a.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

如果这不起作用 - 只需卸载重新安装所有 EF 包(我不知道为什么 - 但这对我有用)对于所有依赖项目,当然是最新的稳定版本。

原因:

按照惯例,EF 将假设 主键 属性是 自动生成的。所以我们需要说 EF 我们将通过我们的代码来完成。但是,尚不清楚为什么 DataAnnotations 不能像这样工作:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }

但流利的 API 效果很好。可能是我两者都用的原因吧。