删除实体,但保留一个相关实体
本文关键字:实体 一个 保留 删除 | 更新日期: 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
。