【问题标题】:EF Code first + Delete Child Object from Parent?EF代码优先+从父对象中删除子对象?
【发布时间】:2011-01-16 21:15:36
【问题描述】:

我的表 Case 和我的另一个表 CaseReplies 之间存在一对多关系。我正在使用 EF Code First,现在想从 Case 对象中删除 CaseReply,但是这样做似乎是不可能的,因为它只是试图从特定的 CaseReply 记录中删除 CaseId 而不是记录本身..

我尝试在数据库级别设置级联删除/更新但运气不佳...

short:Case 只是删除了自身与 CaseReply 之间的关系。它不会删除 CaseReply。

我的代码:

// Case.cs(案例对象)

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

提前致谢。

【问题讨论】:

  • 请发布您的对象模型,包括您可能拥有的任何流畅的 API 代码。
  • 我已经用 CaseRepository 中使用的对象模型更新了帖子。
  • 这是不可能的。由于需要您的关联,因此您应该会因为删除而获得异常。您确定 CaseReply 类上的 CaseId 类型是 int 而不是 int? 吗?
  • @Morteza Manavi - 正如我的帖子所说,它“工作” - 但不是我期望的那样......它应该从数据库中删除 CaseReply 对象,而不是特定 Case 和案例回复。

标签: c# entity-framework repository ef-code-first


【解决方案1】:

如果您希望 EF 在从父对象集合中删除 CaseReply 时将其从 DB 中删除,则必须使用识别关系。这意味着您的CaseReply 必须具有基于IdCaseId 列的复合主键。

【讨论】:

  • 我的 CaseReply 表中有 Id(主键和标识符)和 CaseId (PK) 列..
  • 但是您的映射中没有它。您在数据库中拥有什么并不重要。您在代码优先映射中定义的内容很重要,我只在 Id 上看到 Key 属性。
  • 我刚刚尝试过,它仍然只删除关系而不是对象......
【解决方案2】:

我相信您使用的是 EF CT4?我也有同样的问题并且讨厌它。我认为你的代码完全没问题。

由于您的关联是一对多的,唯一的解决方案是在数据库端设置级联删除。 http://blogs.msdn.com/b/alexj/archive/2009/08/19/tip-33-how-cascade-delete-really-works-in-ef.aspx>

上述解决方案适用于在删除其父记录时删除孤儿。我希望它也能解决你的问题。

【讨论】:

    【解决方案3】:

    如果你想在数据库中删除它,你必须从 context.Replies 中删除。 您现在正在做的是将它从删除关联的案例回复集合中删除。所以你必须打电话:

    context.Replies.Remove(delete)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 2012-01-09
      相关资源
      最近更新 更多