删除实体,但保留一个相关实体

本文关键字:实体 一个 保留 删除 | 更新日期: 2023-09-27 18:03:35

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

要删除的实体记录为:

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并保留所有相关的messagask。

编辑:我使用服务Delete:

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

And I use a repository to Delete the Entity

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

}

Error I get now:

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

谢谢

删除实体,但保留一个相关实体

如果您的关系是可选的(也就是说,从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 = NULL更新MessageAsk

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