我有以下代码:
public class Parent
{
public int ParentId {get;set;}
public ICollection<Child> Children {get;set;}
}
public class Child
{
public int ChildId {get;set;}
public Parent Parent {get;set;}
}
它被EF映射为一对多而无需任何额外的努力。当我用新集合替换Children时(另外3个项目)我在子表中有旧的孤儿实体,如下所示:
Id | Parent_Id
1 NULL <-- orphan
2 NULL <-- orphan
3 NULL <-- orphan
4 1 <-- new
5 1 <-- new
6 1 <-- new
我希望明确地找出关系来消除它们:
modelBuilder.Entity<Child>().HasKey(x => new { x.ChildId, x.ParentId });
modelBuilder.Entity<Parent>().HasMany(x => x.Children).WithRequired().HasForeignKey(x => x.ParentId);
但是我没有孩子的ParentId属性。我只有“父”直接指向父实体。如果我试试
modelBuilder.Entity<Child>().HasKey(x => new { x.ChildId, x.Parent });
我收到错误消息:
属性...不能用作实体的关键属性...因为属性类型不是有效的键类型
有没有办法删除所有不必要的孤儿?
答案 0 :(得分:1)
据我所知,为了识别关系,您需要父母主键作为孩子主键的一部分。然后,EF将允许您从收集中删除该子项并将其删除。
只是让导航属性不起作用。识别关系是数据库级别的概念,因此需要公开的主键ID
请参阅我关于该主题的问题here
答案 1 :(得分:1)
在我的应用程序中,我有一个类似的模型。然而,我没有去除孤儿,而是生产它们。如果我想删除一些子对象,我会按以下方式执行:
//This line attaches a parent object to the session. EF will start monitoring it.
Entry(parent).State = EntityState.Modified;
//This code is responsible for finding children to delete.
foreach (var child in parent.Children.Where(ch => ch.Deleted))
//This line says EF that given child should be removed.
//This line also causes that an object will be removed from Children collection.
Entry(child).State = EntityState.Deleted;
SaveChanges();
已删除是我要设置为 true 的属性,如果我要删除对象。