Код EF сначала + Удалить дочерний объект из родительского? - PullRequest
1 голос
/ 17 января 2011

У меня есть отношение один-ко-многим между моим столом Case и другим моим столом CaseReplies. Я использую EF Code First и теперь хочу удалить CaseReply из объекта Case, однако это невозможно сделать, потому что он просто пытается удалить CaseId из конкретной записи CaseReply, а не самой записи ..

Я попытался установить каскадное удаление / обновление на уровне базы данных без удачи ...

short: Case просто удаляет связь между собой и CaseReply .. он не удаляет CaseReply.

Мой код:

// 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)

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;
    }
}

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 17 января 2011

Если вы хотите, чтобы EF удаляла CaseReply из БД при удалении его из коллекции объектов родителя, вы должны использовать Идентификационные отношения.Это означает, что ваш CaseReply должен иметь составной первичный ключ на основе столбцов Id и CaseId.

0 голосов
/ 02 марта 2011

Вы должны удалить из контекста. Ответы, если вы хотите удалить его в БД. То, что вы делаете сейчас, - это удаление его из коллекции ответов по делу, которая удаляет ассоциацию. Так что вы должны позвонить:

context.Replies.Remove(delete)
0 голосов
/ 18 января 2011

Я полагаю, вы используете EF CT4?У меня была такая же проблема, и я ненавидел ее.Я думаю, что ваш код полностью в порядке.

Поскольку ваша связь одна ко многим, единственным решением является установка каскадного удаления на стороне базы данных.<<a href="http://blogs.msdn.com/b/alexj/archive/2009/08/19/tip-33-how-cascade-delete-really-works-in-ef.aspx" rel="nofollow">http://blogs.msdn.com/b/alexj/archive/2009/08/19/tip-33-how-cascade-delete-really-works-in-ef.aspx>

Приведенное выше решение работает для удаления сирот при удалении их родительской записи.Я надеюсь, что это решит и вашу проблему.

...