【问题标题】:Entity Framework Cannot insert the value NULL into column Identity Specification set to No实体框架无法将值 NULL 插入列标识规范设置为否
【发布时间】:2015-10-18 21:04:06
【问题描述】:

我首先使用实体​​框架代码,最近创建了一个名为 ImportCases 的新 Repo 模型/表。

我已经像其他人一样设置了配置和模型,但是当我在我的代码中到达这一行时:

public int CreateImportantCase(ImportantCase newImportantCase)
        {
            _context.ImportantCases.Add(newImportantCase);

            _context.SaveChanges(); // <--- here

            return newImportantCase.ImportantId;
        }

我收到此错误:

无法将值 NULL 插入“ImportantId”列,表 'MyDatabase.dbo.ImportantCases';列不允许空值。插入 失败。声明已终止。

我的模型/配置如下所示:

型号

public class ImportantCase
{
    public int ImportantId { get; set; }
    public int EvpId { get; set; }
    public string Comment { get; set; }
    public int CategoryId { get; set;}
}

EF 配置

class ImportantCaseConfiguration : EntityTypeConfiguration<ImportantCase>
    {
        public ImportantCaseConfiguration()
        {
            HasKey(x => x.ImportantId);
        }
    }

在调用 create 方法之前,我正在使用视图模型和模型绑定通过视图中的 Post 方法设置新的 ImportantCase

if (imp != null ) // already a record, so update
                {
                    imp.Comment = modifiedExceptionPersonViewModel.Comment;
                    imp.CategoryId = int.Parse(modifiedExceptionPersonViewModel.SelectedCategory);
                    _service.UpdateImportantCase(imp); 
                }
                if (imp == null) //no record so create
                {
                    ImportantCase newImportantCase = new ImportantCase();
                    newImportantCase.Comment = modifiedExceptionPersonViewModel.Comment;
                    newImportantCase.CategoryId = int.Parse(modifiedExceptionPersonViewModel.SelectedCategory);
                    newImportantCase.EvpId = modifiedExceptionPersonViewModel.EvpId;
                    _service.CreateImportantCase(newImportantCase);
                }

我在SaveChanges 之前检查了newImportantCase 对象,它看起来和我预期的一样,将ImportantId 设置为'0',通常EF 只会在写入完成后创建ID。

我注意到的一件事是,当我查看该表的设计时,身份规范设置为No,EF 创建的所有其他表都设置为Yes,我做了什么不同的事情?

注意

EvpId 是从视图返回的视图模型的 ID,我刚刚将类别和注释属性滚动到此视图模型中,以便在控制器中单独处理它们。

编辑

我刚刚意识到,当我最初运行 update-database 时,我愚蠢地将 ImportantId 设置为一个字符串,但后来添加了一个新的迁移来纠正这个问题,没有意识到 EF 没有回顾性地整理身份规范,是有办法解决吗?

【问题讨论】:

  • 要设置身份规范,您可以这样做[Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int ImportantId { get; set; }
  • @Eldho 现在我已将 ImportId 正确设置为 int,如果我删除该表并再次运行 update-database 会发生什么,会对其进行排序吗?
  • 我认为您可以按照上述评论中的说明更新您的 ImportantCase 模型并尝试更新数据库,否则您可以删除表并再次运行

标签: c# entity-framework


【解决方案1】:

在 ImportCase 模型中将 int 更改为 int?

public class ImportantCase {
public int? ImportantId { get; set; }
public int EvpId { get; set; }
public string Comment { get; set; }
public int CategoryId { get; set;} }

【讨论】:

    【解决方案2】:

    我做了以下来纠正这个问题:

    1.) 通过管理工作室删除有问题的表。

    2.) 确保模型已修改为具有实际 Id(您希望将身份规范设置为 Yes 的东西)

    3.) 通过包管理器控制台创建一个新的迁移,类似于:

    add-migration "Set ImportantId as Identity Specification"
    

    4.) 如果没有任何变化,您将看到一个空的 Up()Down() 方法

    5.) 使用最初引入此表的迁移内容修改这些内容,但请确保这次将 Id 设置为 int,因此:

    public partial class addedimportantcasetable : DbMigration
        {
            public override void Up()
            {
                CreateTable(
                    "dbo.ImportantCases",
                    c => new
                        {
                            ImportantId = c.String(nullable: false, maxLength: 128),
                            EvpId = c.Int(nullable: false),
                            Comment = c.String(),
                            CategoryId = c.Int(nullable: false),
                        })
                    .PrimaryKey(t => t.ImportantId);                
            }
    
            public override void Down()
            {
                DropTable("dbo.ImportantCases");
            }
        }
    

    被复制到新的迁移中,但略有改动:

    public partial class SetImportantIdasIdentitySpecification : DbMigration
        {
            public override void Up()
            {
                CreateTable(
                   "dbo.ImportantCases",
                   c => new
                   {
                       ImportantId = c.Int(nullable: false, identity: true),
                       EvpId = c.Int(nullable: false),
                       Comment = c.String(),
                       CategoryId = c.Int(nullable: false),
                   })
                   .PrimaryKey(t => t.ImportantId);
            }
    
            public override void Down()
            {
                DropTable("dbo.ImportantCases");
            }
        }
    

    【讨论】:

    • 删除整个数据库并让 EF 重新创建它(我首先使用代码)为我解决了这个问题,因为我仍处于开发阶段,所以我让数据库下降。我想这也行。
    猜你喜欢
    • 1970-01-01
    • 2017-03-05
    • 2016-07-05
    • 2012-09-25
    • 2019-11-29
    • 1970-01-01
    • 2011-05-25
    • 2012-06-25
    相关资源
    最近更新 更多