【发布时间】:2014-05-10 13:47:13
【问题描述】:
我有以下两个类:
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 设置为 null。
问题是,我收到错误“违反主键约束 'PK_dbo.Child'。无法在对象 'dbo.Child' 中插入重复键。重复键值为 (0, 2)。”当我创建一个有孩子的新父母,然后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 键以使其正常工作吗?
【问题讨论】:
-
您是否尝试在子实体 ID 之上添加关键属性。我知道您已经通过 fluentapi 进行操作。我会使用 sql profiler 来查看 sql server 中生成的内容。
-
设置为Cascade-on-Delete,不要用可选部分组成假密钥。
-
删除时的级联将起作用,但那是当我删除父级时,它的子级也将被删除。问题是, parent.Children.Remove(child) 只是删除关系,而不是从数据库中删除子项。
-
那是因为你说
.HasOptional(c => c.Parent)。 -
将所有键更改为字符串,并在 C# 中手动生成 GUID,并将 .HasOptional 更改为 .HasRequired - 按预期工作。我只是不明白为什么它不适用于整数。
标签: c# sql entity-framework ef-code-first