【发布时间】:2017-12-14 12:31:27
【问题描述】:
我有一个方法可以接收我要删除的对象的 ID IEnumerable<Guid>。一种建议的方法如下
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
DataContext.Attach(tempInstance); // Exception here
DataContext.Remove(tempInstance);
}
如果对象尚未加载到内存中,这可以正常工作。但我的问题是,当它们已经加载时,Attach 方法会抛出InvalidOperationException - The instance of entity type 'MyEntity' cannot be tracked because another instance with the key value 'Id:...' is already being tracked。如果我使用DataContext.Remove 而不调用Attach,也会发生同样的情况。
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
DataContext.Remove(tempInstance); // Exception here
}
我不想使用DataContext.Find 来获取已加载对象的实例,因为如果对象尚未加载,这会将其加载到内存中。
我无法使用DataContext.ChangeTracker 来查找已加载的对象,因为那里只显示状态已修改的对象,并且我的对象可能已加载和未修改。
以下方法在设置EntityEntry.State 时会抛出相同的InvalidOperationException,即使我在MyEntity 上覆盖GetHashCode 和Equals 以确保字典查找将它们视为同一个对象。
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
EntityEntry entry = DataContext.Entry(tempInstance);
entry.State == EntityState.Deleted; // Exception here
}
目前我发现的唯一方法是可以在不知道对象是否如下的情况下实现按ID删除对象:
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
try
{
DataContext.Attach(tempInstance); // Exception here
}
catch (InvalidOperationException)
{
}
DataContext.Remove(tempInstance);
}
奇怪的是,在尝试Attach 它遇到异常后,我能够毫无错误地调用DataContext.Remove(tempInstance),但此时它确实可以正常工作,并且当DataContext.SaveChanges 时,它还会从数据库中删除正确的行被执行。
我不喜欢捕捉异常。有没有实现我想要的“好”方法?
注意:如果类有自引用,那么您需要将对象加载到内存中,以便 EntityFrameworkCore 可以确定删除对象的顺序。
【问题讨论】: