简体   繁体   中英

EF Code first + Delete Child Object from Parent?

I have a one-to-many relationship between my table Case and my other table CaseReplies . I'm using EF Code First and now wants to delete a CaseReply from a Case object, however it seems impossible to do such thing because it just tries to remove the CaseId from the specific CaseReply record and not the record itself..

I've tried to set cascade delete/update at database level without luck...

short: Case just removes the relationship between itself and the CaseReply.. it does not delete the CaseReply.

My code:

// Case.cs (Case Object)

public class Case
{
    [Key]
    public int Id { get; set; }

    public string Topic { get; set; }

    public string Message { get; set; }

    public DateTime Date { get; set; }

    public Guid UserId { get; set; }

    public virtual User User { get; set; }

    public virtual ICollection<CaseReply> Replies { get; set; }
}

// CaseReply.cs (CaseReply Object)

public class CaseReply
{
    [Key]
    public int Id { get; set; }

    public string Message { get; set; }

    public DateTime Date { get; set; }

    public int CaseId { get; set; }

    public Guid UserId { get; set; }

    public virtual User User { get; set; }

    public virtual Case Case { get; set; }
}

// RepositoryBase.cs

public class RepositoryBase<T> : IRepository<T> where T : class
{
    public IDbContext Context { get; private set; }
    public IDbSet<T> ObjectSet { get; private set; }

    public RepositoryBase(IDbContext context)
    {
        Contract.Requires(context != null);

        Context = context;

        if (context != null)
        {
            ObjectSet = Context.CreateDbSet<T>();

            if (ObjectSet == null)
            {
                throw new InvalidOperationException();
            }
        }
    }

    public IRepository<T> Remove(T entity)
    {
        ObjectSet.Remove(entity);
        return this;
    }

    public IRepository<T> SaveChanges()
    {
        Context.SaveChanges();
        return this;
    }
}

// CaseRepository.cs

public class CaseRepository : RepositoryBase<Case>, ICaseRepository
{
    public CaseRepository(IDbContext context)
            : base(context)
    {
        Contract.Requires(context != null);
    }

    public bool RemoveCaseReplyFromCase(int caseId, int caseReplyId)
    {
        Case caseToRemoveReplyFrom = ObjectSet.Include(x => x.Replies).FirstOrDefault(x => x.Id == caseId);
        var delete = caseToRemoveReplyFrom.Replies.FirstOrDefault(x => x.Id == caseReplyId);

        caseToRemoveReplyFrom.Replies.Remove(delete);

        return Context.SaveChanges() >= 1;
    }
}

Thanks in advance.

If you want EF to remove CaseReply from DB when you remove it from parent's object collection, you have to use Identifying relations. It means that your CaseReply must have composite primary key based on Id and CaseId columns.

I believe you are using EF CT4? I had the same problem too and hated it. I think your code is totally fine.

Since your association is one to many, the only solution is to setting cascading delete at database side. < http://blogs.msdn.com/b/alexj/archive/2009/08/19/tip-33-how-cascade-delete-really-works-in-ef.aspx >

The above solution works for deleting orphans on deleting their parent record. I hope it will solve your issue too.

You have to remove from context.Replies if you want to delete it in db. What you are doing right now is removing it from case's replies collection which removes the association. So you have to call:

context.Replies.Remove(delete)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM