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)
精彩评论