实体框架6在插入嵌套标识关系时插入null作为主键

时间:2016-06-10 23:01:41

标签: c# .net sql-server entity-framework entity-framework-6

我使用EF6 Code First定义了四个实体:

try.. except ValueError

(我省略了导航属性,但它们就在那里。)

使用如下定义的关系:

public class Item1
{
    [Key]
    [StringLength(50)]
    public string Name { get; set; }
}

public partial class Item2
{
    [Key]
    [Column(Order = 0)]
    [StringLength(50)]
    public string Item1Name { get; set; }

    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    public string Name { get; set; }
}

public partial class Item3
{
    [Key]
    [Column(Order = 0)]
    [StringLength(50)]
    public string Item1Name { get; set; }

    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    public string Item2Name{ get; set; }

    [Key]
    [Column(Order = 2)]
    [StringLength(50)]
    public string Name { get; set; }
}

public partial class Item4
{
    [Key]
    [Column(Order = 0)]
    [StringLength(50)]
    public string Item1Name { get; set; }

    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    public string Item2Name{ get; set; }

    [Key]
    [Column(Order = 2)]
    [StringLength(50)]
    public string Item3Name{ get; set; }

    [Key]
    [Column(Order = 3)]
    [StringLength(50)]
    public string Name{ get; set; }
}

现在,当我尝试将Item3插入existingItem2.Item3s时,就像这样:

modelBuilder.Entity<Item1>()
            .HasMany(e => e.Item2s)
            .WithRequired(e => e.Item1)
            .HasForeignKey(e => new { e.Item1Name})
            .WillCascadeOnDelete(false);

modelBuilder.Entity<Item2>()
            .HasMany(e => e.Item3s)
            .WithRequired(e => e.Item2)
            .HasForeignKey(e => new { e.Item1Name, e.Item2Name })
            .WillCascadeOnDelete(false);

modelBuilder.Entity<Item3>()
            .HasMany(e => e.Item4s)
            .WithRequired(e => e.Item3)
            .HasForeignKey(e => new { e.Item1Name, e.Item2Name, e.Name})
            .WillCascadeOnDelete(false);

我收到以下错误:

  

无法将值NULL插入列'Item1Name',表'Database.dbo.Item4s';列不允许空值。 INSERT失败。\ r \ n语句已终止。

奇怪的是,在我将一个Item3插入到existingItem2.Item3s而没有嵌套的Item4之后,我可以使用上面的过程插入嵌套的项目而没有任何错误。我已尝试用Item3 newItem3 = new Item3(); newItem3.Item4s.Add(new Item4()); existingItem2.Item3s.Add(newItem3); db.SaveChanges(); 明确指定所有键,但它没有任何区别。什么可以在这里发挥作用?

修改

我缩小了这个错误,为什么它有时会发生,有时候不会发生。在我的程序中,除了我描述的内容之外,我还设置了[DatabaseGenerated(DatabaseGeneratedOption.None)]。事实证明,如果这实际上会改变值(它总是设置),EF将生成一个失败的查询。似乎是EF中的一个错误,对吧?我这样解决了这个问题:

existingItem2.someUnrelatedNonKeyIntegerValue = someValue;

(顺便说一句,整数在名称中不包含ID,并且实际上没有在数据库中标记为键。)

1 个答案:

答案 0 :(得分:0)

对数据库表一无所知......

如果映射到Item1Name的列与模型中的属性具有相同的数据类型,则可以通过更改表列以允许空值或初始化构造函数中的模型属性来解决此问题。

public partial class Item3
{
    public Item3()
    {
     Item1Name = string.empty;
     Item2Name = string.empty;
     Name = string.empty;
    }

    [Key]
    [Column(Order = 0)]
    [StringLength(50)]
    public string Item1Name { get; set; }

    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    public string Item2Name{ get; set; }

    [Key]
    [Column(Order = 2)]
    [StringLength(50)]
    public string Name { get; set; }
}