变化方面,我有一个巨大的JSON格式的“扁平化”的对象列表,(对应于扁平物体约20桌)计算一个比较复杂的关系数据库架构。我想我的新关系数据库的扁平物体插入自动:如何丢弃EF核心
foreach (var flattenedObject in flattenedObjects)
{
_repository.Insert(flattenedObject).Wait();
//some time logging, etc
}
的Insert()
方法为许多不同表中相关对象的调用AddRangeAsync()
和AddAsync()
。
由于扁平对象是传统的,我会说他们的约0.001%是畸形的,将违反DB的约束 - 例如试图插入在其中一个表的重复复合主键。
我希望这些罕见的错误,因此,我的想法是 - 包装在一个事务中的整体Insert()
操作 - 如果任何一块的操作是无效的,只是不插入任何东西,记录错误,这样我就可以修改扁平在再次尝试之前手动对象。因此,我的代码看起来有点类似于此:
public async Task Insert(FlattenedObject fo)
{
using (var transaction = _context.Database.BeginTransaction())
{
try
{
//magical code that calls AddAsync for multiple tables
}
catch (Exception ex)
{
transaction.Rollback()
//logging
}
}
}
但是,如果在我的try块某处发生错误(我尝试插入违反复合主键的对象),我的整个上下文对象被损坏。
导致异常的对象仍然留在我的DbContext和不同的事务以下任何调用AddAsync()
触发一个新的异常。
我试图重建我的DbContext和回购在foreach
循环上述每一个新的对象 - 但即便如此,如果我查询:
_context.ChangeTracker.Entries().Where(e => e.State != EntityState.Unchanged);
我看到我的旧的对象仍然是的DbContext的新实例。
是否有任何(优雅的)的方式来告诉我的情况下,可以将所有挂起的更改 - 这样我就可以把它放在每当出现错误catch块?我希望在失败的事务中发生的所有事情都留在那里,不会泄漏。
不应该包括你在下面的条件。凡(E => e.Entity!= NULL && e.state == EntityState.Added)分离 – CPR43
在此之前,将在那里插入引起了我目前的情况是真实的麻烦。然而,有人可能会与更新有类似的问题,所以我会留下这个答案,因为它是复制+粘贴,如果别人面临这样的问题。 – nikovn
代码有问题吗?潜在的错误可能? 为什么downvote? – nikovn