【问题标题】:Code first - Cannot insert the value NULL into column 'Id'代码优先 - 无法将值 NULL 插入“Id”列
【发布时间】:2011-12-13 01:45:13
【问题描述】:

这是我的代码,很简单……

 var newUser = new User();
        newUser.Id=id;
        newUser.Email = email;
       this.DataContext.Set<User>().Add(newUser);
        this.DataContext.SaveChanges();

我得到的错误是this.DataContext.SaveChanges(); 的 sqlexception 声明:

无法将值 NULL 插入到表的“Id”列中 'xxxxx.dbo.Users';列不允许空值。插入失败。

我已经调试过,发现 newUser 中的 Id & Email 有值 this.DataContext.Set&lt;User&gt;().Add(newUser);

如果是这种情况,值如何变为空?

错误堆栈跟踪:

[DbUpdateException: An error occurred while updating the entries. See the inner exception for details.]
   System.Data.Entity.Internal.InternalContext.SaveChanges() +204
   System.Data.Entity.Internal.LazyInternalContext.SaveChanges() +23
   System.Data.Entity.DbContext.SaveChanges() +20

我一直无法理解或解决这个问题......

非常感谢您对此提供的任何帮助...

问候 阿纳布

解决方案

好的,感谢 Ladislav 为我指明了正确的方向: 添加属性[DatabaseGenerated(DatabaseGeneratedOption.None)] 解决了这个问题。

【问题讨论】:

  • id的类型是什么?会不会是在数据库中生成密钥时出了问题?
  • type 在 sqlserver 中是 bigint,在 User 类中它很长。而且当我使用没有 codefirst 的普通实体框架时,它可以工作
  • 你是如何映射用户的?默认情况下,EF 代码首先需要在数据库中生成 Id 值(通过身份设置)。
  • 我的用户类有两个字段,其中 Id 具有 [key] 属性。在 db 中,我已将 Id 设为主键,但已声明 IsIdentity =no ,因此不会在 db 中生成该值。 @Ladislav:你说的可能是问题所在,我该如何解决?我不能让 isIdentity=yes
  • 好的,感谢 Ladislav 为我指明了正确的方向:添加属性 [DatabaseGenerated(DatabaseGeneratedOption.None)] 解决了问题。

标签: entity-framework-4.1 ef-code-first


【解决方案1】:

我遇到了同样的问题,找到了你的问题,然后注意到了这个Entity Framework 4.1 code-first KeyAttribute as non-identity column 问题(它的属性解决了我的问题)。

如果您将用户定义为:

public class User
{
    [DataMember, Required, Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public long ID { get; set; }

    [DataMember]
    public string Email { get; set; }
}

这里的关键是放置属性:

  • 数据库生成

到 ID 列。显然,我们要解决的问题是 Entity Framework 在默认情况下希望使用作为身份的键进行插入。

【讨论】:

    【解决方案2】:

    参考this post 似乎实体框架默认情况下希望您插入到标识列中。

    要解决这个尝试:

    modelBuilder.Entity<BOB>()
        .HasKey(p => p.Id)
        .Property(p => p.Id)
        .StoreGeneratedPattern = StoreGeneratedPattern.None;
    
    builder.Entity<BOB>().MapSingleType().ToTable("BOB");
    

    或在 POCO 中装饰您的钥匙:

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)] //Fixed typo
    public Int64 PolicyID { get; set; }
    

    【讨论】:

    • 我相信该属性的枚举标志是“DatabaseGeneratedOption”而不是“DatabaseGenerationOption”
    • 它也对我有用,任何人都可以解释为什么会发生此属性如何解决问题。
    【解决方案3】:

    我通过将列属性上的StoreGeneratedPattern 设置为Computed 来解决此问题。

    下面一步一步来:

    1. 打开您的 EDMX(在 Visual Studio 中双击)
    2. 右键单击导致问题的列,选择属性。
    3. StoreGeneratedPattern 更改为Computed

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2020-10-21
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 2016-07-05
      相关资源
      最近更新 更多