删除实体但保留其中一个相关实体

时间:2013-03-11 18:50:03

标签: c# entity-framework

我需要删除一个实体的记录,但保留与之相关的另一个实体的所有记录:

要删除的实体记录是:

public class Ask
{
    // Primary properties
    public int Id { get; set; }
    public string Title { get; set; }
    public string Message { get; set; }
    public DateTime DateCreated { get; set; }
}

删除Ask记录后我想保留的相关记录属于MessageAsk:

public class Message
{
    // Primary properties
    public int Id { get; set; }
    public string NameFrom { get; set; }
    public string EmailFrom { get; set; }
    public string TelephoneFrom { get; set; }
    public string Title { get; set; }
    public string MessageText { get; set; }
    public bool? Approved { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DateRead { get; set; }

    // Navigation properties
    public Member MemberFrom { get; set; }
    public Member MemberTo { get; set; }
    public MessageType MessageType { get; set; }
    public Message MessageParent { get; set; }
}

public class MessageAsk : Message
{
    public Ask Ask { get; set; }
}

恢复,我想删除一个Ask并保留所有相关的MessageAsk。

编辑: 我使用服务删除:

    private readonly IRepository<Ask> _askRepository;
    private readonly IRepository<MessageAsk> _messageAskRepository;

    public bool Delete(int askId)
    {
        try
        {
            Ask askToDelete = _askRepository.GetById(askId);

            IList<MessageAsk> relatedMessageAsks = _messageAskRepository.Query.Where(m => m.Ask.Id == askId).ToList();

            _askRepository.Delete(askToDelete);

            _askRepository.Save();

         }
        catch 
        { 
            return false; 
        }

        return true;
    }

我使用存储库来删除实体:

public class Repository<T> : IRepository<T> where T : class
{
    protected DbContext _dataContext;
    protected DbSet<T> _dbSet;

    public Repository(DbContext context)
    {
        _dataContext = context;
        _dbSet = _dataContext.Set<T>();
    }

    public T NewEntityInstance()
    {
        return _dbSet.Create();
    }

    public void Delete(T entity)
    {
        if (_dataContext.Entry(entity).State == EntityState.Detached)
        {
            _dbSet.Attach(entity);
        }
        _dbSet.Remove(entity);
    }

   public virtual void Delete(object id)
    {
        T entity = _dbSet.Find(id);

        Delete(entity);
    }

    public T GetById(int id)
    {
        return _dbSet.Find(id);
    }

    public virtual IQueryable<T> Query
    {
        get
        {
            return _dbSet.AsNoTracking(); <------ SOURCE OF THE PROBLEM - I HAD TO REMOVE THE ASNOTRACKING OPTION TO SOLVE THE PROBLEM
        }
    }

}

我现在得到的错误:

"The DELETE statement conflicted with the REFERENCE constraint "FK_Messages_Asks". The conflict occurred in database "Heelp", table "dbo.Messages", column 'Ask_Id'.

由于

1 个答案:

答案 0 :(得分:1)

如果您的关系可选(即,从MessageAsk表到Ask表的外键允许NULL值),您可以这样做方式:

using (var context = new MyContext())
{
    var askToDelete = context.Asks.Single(a => a.Id == askToDeleteId);
    var relatedMessageAsks = context.MessageAsks
        .Where(m => m.Ask.Id == askToDeleteId)
        .ToList();
    // or just: context.MessageAsks.Where(m => m.Ask.Id == askToDeleteId).Load();

    context.Asks.Remove(askToDelete);
    // or DeleteObject if you use ObjectContext

    context.SaveChanges();
}

(或context.Messages.OfType<MessageAsk>()...代替context.MessageAsks...,如果您的上下文中没有派生类型的集合)

您无需在此明确将MessageAsk.Ask属性设置为null。 EF会在删除askToDelete后自动执行此操作,并在数据库中使用FK = MessageAsk更新NULL

如果需要关系(允许FK没有NULL s),则它不起作用,因为当主体(askToDelete)将会违反数据库中的引用外键约束时删除。在这种情况下,您需要在删除relatedMessageAsks之前将Ask分配给另一个askToDelete