考虑旧数据库的这个(令人困惑的)实体模型:
如您所见,模型Blog
的集合中有Entry
个集合,每个集合指向一个博客Post
。箭头的尖端指向关系的主体/父母。至少这是EF核心基于外键存储位置看到它的方式。
不幸的是,Entry
和Post
之间的FK是错误的处理方法,因为Post
实际上是Entry
的子元素;也就是说,当我从Entry
删除Blog
时,关联的Post
也应删除。
由于我无法更改旧数据库的架构,所以我想知道如何建议EF级联删除Post
,尽管它不认为它们是{{1 }}。
我尝试明确指定Entry
无济于事:
DeleteBehavior
我还尝试将导航属性modelBuilder.Entity<Entry>()
.HasOne(e => e.Post)
.WithOne(p => p.Entry)
.OnDelete(DeleteBehavior.Cascade);
设置为指示Post.Entry
不能没有其Post
才能生存,但这也没有帮助:
Entry
我目前正在检查owned entity types是否可以提供帮助,但我对此表示怀疑。
我想我需要的是一种明确声明实体关系的父/本的方法。像SetPrincipalEntityType()
之类的东西。
当然,我总是可以手动删除public class Post {
// ...
[Required]
[InverseProperty(nameof(Entry.Post))]
public Entry Entry { get; set; }
}
,但是我正试图避免这种情况。
有任何想法吗?
我用集成测试创建了一个test project,可用于重现该问题:
Post
答案 0 :(得分:0)
我在EF Core GitHub页面上发布了相同的问题。 solution posted there的想法是在SaveChanges()
的替代中找到孤立的实体,然后手动将其删除:
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
// Note that this is internal code to force cascade deletes to happen.
// It may stop working in any future release.
ChangeTracker.DetectChanges();
this.GetService<IStateManager>().GetEntriesToSave();
try
{
ChangeTracker.AutoDetectChangesEnabled = false;
foreach (var entry in ChangeTracker
.Entries<CritiqueText>()
.Where(e => Entry(e.Entity.Review).State == EntityState.Deleted))
{
entry.State = EntityState.Deleted;
}
}
finally
{
ChangeTracker.AutoDetectChangesEnabled = true;
}
return base.SaveChanges(acceptAllChangesOnSuccess);
}
我接受了这一点,并以此为基础构建了基于属性的解决方案,您可以在test project repo中找到它。