我对使用实体框架的asp.net核心是一个新手。我正在尝试安排模型,以便在删除GrandParent条目时也删除父条目,然后在删除父条目时删除父条目中的DerivedTypeA和DerivedTypeB条目。
当前,当删除GrandParent条目时,Parent条目会删除,但是条目DerivedTypeA和DerivedTypeB。我花了很长时间试图弄清楚如何实现此功能。
public class GrandParent
{
public int GrandParentID { get; set; }
public string Title { get; set; }
public virtual Parent Parent{ get; set; }
}
public class Parent
{
[ForeignKey("GrandParent")]
public int ParentID { get; set; }
public DerivedTypeA DerivedTypeA { get; set; }
public DerivedTypeB DerivedTypeB { get; set; }
}
public abstract class BaseEntity
{
public int ID { get; set; }
public string Description { get; set; }
}
public class DerivedTypeA: BaseEntity
{
public string SomeUniqueProperty { get; set;}
}
public class DerivedTypeB: BaseEntity
{
public string SomeOtherUniqueProperty { get; set;}
}
我的情况如下
public class PortalContext : DbContext
{
public PortalContext(DbContextOptions<PortalContext> options) : base(options)
{
}
public DbSet<GrandParent> GrandParents { get; set; }
public DbSet<Parent> Parents { get; set; }
public DbSet<BaseEntity> BaseEntities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<GrandParent>().ToTable("GrandParent");
modelBuilder.Entity<Parent>().ToTable("Parent");
modelBuilder.Entity<BaseEntity>().ToTable("BaseEntity");
}
}
以下是post delete http请求,在该请求中,我尝试手动删除BaseEntity类型的两个子类,但是在保存上下文时出现错误/异常。
public class GrandParentsController : Controller
{
private readonly PortalContext _context;
public GrandParentsController(PortalContext context)
{
_context = context;
}
// POST: GrandParents/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var grandParent = await _context.GrandParents
.Include(w => w.Parent)
.Include(q => q.Parent.DerivedTypeA)
.Include(j => j.Parent.DerivedTypeB)
.FirstOrDefaultAsync(c => c.GrandParentID == id);
if (grandParent == null)
{
return RedirectToAction(nameof(Index));
}
try
{
BaseEntity derivedTypeA = await _context.BaseEntities
.FirstOrDefaultAsync(m => m.ID == grandParent.Parent.DerivedTypeA.ID);
_context.BaseEntities.Remove(derivedTypeA);
BaseEntity derivedTypeB = await _context.BaseEntities
.FirstOrDefaultAsync(m => m.ID == grandParent.Parent.DerivedTypeB.ID);
_context.BaseEntities.Remove(derivedTypeB);
_context.GrandParents.Remove(grandParent);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error(uncomment ex variable name and write a log.)
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
}
假定在调用“ _context.SaveChangesAsync()”时引发了DbUpdateException,则Parent条目中的DerivedTypeA和DerivedTypeB属性不为null。
环顾四周后,有人建议在OnModelCreating方法中添加一些类似内容。
modelBuilder.Entity<DerivedTypeA>()
.HasOne(p => p.Parent)
.WithOne(b => b.DerivedTypeA)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK_BaseEntity_BaseEntities_ParentID");
这没有用,因为BaseEntity类没有Parent属性,如果我将该属性放入(我尝试过),也不会起作用。是否有人有任何想法如何实现这种功能性?在我不确定解决方案之前,似乎已经看到了继承和级联删除问题。