EF Code First - 无法将值 NULL 插入列

Posted

技术标签:

【中文标题】EF Code First - 无法将值 NULL 插入列【英文标题】:EF Code First - Cannot insert the value NULL into column 【发布时间】:2014-10-30 11:05:08 【问题描述】:

所以我有这个 Code-First 类:

[Table("Session")]
public partial class Session

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SessionID  get; set; 

    public DateTime Start  get; set; 

    public DateTime End  get; set; 

    [StringLength(255)]
    public string Type  get; set; 

    public int PatientID  get; set; 

    public virtual Patient Patient  get; set; 

我使用迁移,并尝试在我的初始化程序中为 Sessions 表播种:

IList<Session> defaultSessions = new List<Session>();
defaultSessions.Add(new Session()

    Start = DateTime.Parse("09/01/2014 14:00:00"),
    End = DateTime.Parse("09/01/2014 14:10:00"),
    Type = "pharyngeal",
    PatientID = 1,
);
foreach (Session session in defaultSessions)

    context.Sessions.Add(session);

SessionID 应该是主键,并且是自动递增的,这就是你使用[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 的原因吧?

我仍然收到此错误:

无法将值 NULL 插入到不允许的列表列中 空值。插入失败。声明已终止

数据库中的表是这样的(注意我用的是LocalDB,数据库在mssqllocaldb实例下: 我做错了什么?

编辑: 我注意到在数据库中,身份是FALSE,看这个截图: 这让我感到很奇怪,因为在最新的迁移中,我对身份进行了修复(它只是我在这个问题中提供的类),文件看起来像这样:

public partial class IdentityFixes : DbMigration

    public override void Up()
    
        DropPrimaryKey("dbo.Admin");
        DropPrimaryKey("dbo.Session");
        AlterColumn("dbo.Admin", "AdminID", c => c.Int(nullable: false, identity: true));
        AlterColumn("dbo.Session", "SessionID", c => c.Int(nullable: false, identity: true));
        AddPrimaryKey("dbo.Admin", "AdminID");
        AddPrimaryKey("dbo.Session", "SessionID");
    

    public override void Down()
    
        DropPrimaryKey("dbo.Session");
        DropPrimaryKey("dbo.Admin");
        AlterColumn("dbo.Session", "SessionID", c => c.Int(nullable: false));
        AlterColumn("dbo.Admin", "AdminID", c => c.Int(nullable: false));
        AddPrimaryKey("dbo.Session", "SessionID");
        AddPrimaryKey("dbo.Admin", "AdminID");
    

如您所见,在修复中身份设置为 true。我做了Update-Database 所以我不明白为什么这不起作用..

【问题讨论】:

您是否尝试过在数据库上运行分析器以查看实际发送的查询? @MattC 不,我没有,因为我不知道您在说什么以及如何做到这一点。根据我能找到的有关实体框架的所有文档,这不应该有效吗? 您可以获得 EFProfiler(使用 EF 时的关键工具)的演示,将其集成到您的应用程序(Main 中的单行)并查看发送到 SQL 的语句。您的配置看起来不错,因此调试的唯一方法是查看 EF 发送到数据库的内容。您也可以尝试将new Session() 替换为context.Sessions.Create() 在 SessionID 列的属性中,“Is Identity”是否设置为 true? Update-Database -verbose,确保解决方案中的启动项目和PMC上的默认项目是包含DbContext的项目 【参考方案1】:

我在将迁移应用到现有数据库时遇到了类似的问题,所以我创建了一个空迁移并使用 SQL 代码,这是我的示例:

public override void Up()

  DropForeignKey("dbo.Bar", "FooId", "dbo.Foo");
  Sql("IF object_id(N'[dbo].[FK_Bar_Foo]', N'F') IS NOT NULL ALTER TABLE [dbo].[Bar] DROP CONSTRAINT [FK_Bar_Foo]");
  Sql("CREATE TABLE [dbo].[FooTemp] ([Id] int NOT NULL)");
  Sql("INSERT INTO [dbo].[FooTemp] ([Id]) SELECT [Id] FROM [dbo].[Foo]");
  Sql("DROP TABLE [dbo].[Foo]");
  Sql("CREATE TABLE [dbo].[Foo] ([Id] int IDENTITY (1,1) NOT NULL)");
  Sql("SET IDENTITY_INSERT [dbo].[Foo] ON");
  Sql("INSERT INTO [dbo].[Foo] ([Id]) SELECT [Id] FROM [dbo].[FooTemp]");
  Sql("SET IDENTITY_INSERT [dbo].[Foo] OFF");
  Sql("DROP TABLE [dbo].[FooTemp]");
  AddPrimaryKey("dbo.Foo", "Id");
  AddForeignKey("dbo.Bar", "FooId", "dbo.Foo", "Id");


public override void Down()

  DropForeignKey("dbo.Bar", "FooId", "dbo.Foo");
  Sql("CREATE TABLE [dbo].[FooTemp] ([Id] int NOT NULL)");
  Sql("INSERT INTO [dbo].[FooTemp] ([Id]) SELECT [Id] FROM [dbo].[Foo]");
  Sql("DROP TABLE [dbo].[Foo]");
  Sql("CREATE TABLE [dbo].[Foo] ([Id] int NOT NULL)");
  Sql("INSERT INTO [dbo].[Foo] ([Id]) SELECT [Id] FROM [dbo].[FooTemp]");
  Sql("DROP TABLE [dbo].[FooTemp]");
  AddPrimaryKey("dbo.Foo", "Id");
  AddForeignKey("dbo.Bar", "FooId", "dbo.Foo", "Id");

HTH

【讨论】:

以上是关于EF Code First - 无法将值 NULL 插入列的主要内容,如果未能解决你的问题,请参考以下文章

无法在EF Code First中创建复合主键

15.翻译系列:EF 6中的级联删除EF 6 Code-First 系列

EF 4 Code First:无法检查模型兼容性,因为EdmMetadata类型未包含在模型中

如何使用 EF Core Code-First 创建具有子类别的类别表? [复制]

EF4 CTP5 Code First 方法忽略表属性

EF6 Code First Lazy Load导致空集合