我有以下两个类:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Child> Children { get; set; }
public Parent()
{
Children = new List<Child>();
}
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
然后是数据上下文中的Fluent设置:
modelBuilder.Entity<Child>()
.HasKey(c => new { c.Id, c.ParentId })
.HasOptional(c => c.Parent)
.WithMany(p => p.Children)
.WillCascadeOnDelete(true);
我执行此操作以便在我说parent.Children.Remove(aChild);
时实际删除子对象,而不是仅将其设置为ParentId
。
问题是,我收到错误&#34;违反PRIMARY KEY约束&#39; PK_dbo.Child&#39;。无法在对象&#39; dbo.Child&#39;中插入重复的密钥。重复键值为(0,2)。&#34;当我创建一个有孩子的新父母,然后db.SaveChanges()
:
Parent p = new Parent { Name = "Quarterbacks" };
p.Children.Add(new Child { Name = "Brady" });
p.Children.Add(new Child { Name = "P. Manning" });
p.Children.Add(new Child { Name = "Kaepernick" });
p.Children.Add(new Child { Name = "Wilson" });
p.Children.Add(new Child { Name = "Rodgers" });
db.Parents.Add(p);
db.SaveChanges();
我认为在插入时会自动生成整数主键。我该怎么办?我应该将键更改为字符串并在C#中创建GUID键才能使其生效吗?
答案 0 :(得分:0)
我相信对于复合键,密钥的任何部分都没有标记为默认情况下的 ,即使不是整数键也是如此(简单就是这样) ,非复合键)。您可能必须明确地将Identity
选项添加到Child
实体的Id
属性中:
modelBuilder.Entity<Child>()
.Property(c => c.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
我有点担心你Child
键的第二部分可以为空。也许EF确实允许这样做,但数据库不一定:我认为,使用SQL Server例如可以为空的关键部分是禁止的。也许,其他数据库可以解决这个问题。您显然的目标是识别关系(从父项中删除子项时将其从数据库中删除的那种),但是需要父项和父项之间的必需(非可选)关系。孩子,据我所知。