实体框架核心级联删除和继承以及父实体

时间:2019-12-06 10:41:08

标签: c# asp.net entity-framework asp.net-core entity-framework-core

我对使用实体框架的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属性,如果我将该属性放入(我尝试过),也不会起作用。是否有人有任何想法如何实现这种功能性?在我不确定解决方案之前,似乎已经看到了继承和级联删除问题。

0 个答案:

没有答案