相关疑难解决方法(0)

实体框架中最快的插入方式

我正在寻找插入Entity Framework的最快方法.

我问这个是因为你有一个活跃的TransactionScope并且插入很大(4000+).它可能持续超过10分钟(事务的默认超时),这将导致事务不完整.

c# sql entity-framework

640
推荐指数
17
解决办法
38万
查看次数

如何在EF Core中放弃对上下文的更改

我有一个巨大的json格式的"扁平"对象列表,以及一个有点复杂的关系数据库模式(大约有20个表对应于展平对象).我正在尝试在新的关系数据库中自动插入那些展平的对象:

foreach (var flattenedObject in flattenedObjects)
{
    _repository.Insert(flattenedObject).Wait();
    //some time logging, etc
}
Run Code Online (Sandbox Code Playgroud)

Insert()方法调用AddRangeAsync(),并AddAsync()为一些在不同的表相关的对象.

由于扁平化对象是遗留的,我会说它们中约有0.001%是格式错误并且会违反数据库约束 - 例如尝试在其中一个表中插入重复的复合主键.

我期待这些罕见的错误,因此我的想法是 - 将整个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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我的try块中某处发生错误(我尝试插入违反复合主键的对象),我的整个上下文对象就会变坏.

导致异常的对象仍然保留在我的DbContext中,并且AddAsync()在另一个事务中的任何后续调用都会触发新的异常.

我尝试为foreach上面的循环中的每个新对象重新创建我的DbContext和repo - 但即使这样,如果我查询:

_context.ChangeTracker.Entries().Where(e => e.State != EntityState.Unchanged);
Run Code Online (Sandbox Code Playgroud)

我看到我的旧对象仍然在dbContext的新实例中.

是否有任何(优雅)方式告诉我的上下文重置所有挂起的更改 - 以便每当发生错误时我都可以将它放在catch块中?我希望在失败的交易中发生的一切都留在那里而不是泄漏.

.net c# entity-framework entity-framework-core

8
推荐指数
2
解决办法
4830
查看次数

标签 统计

c# ×2

entity-framework ×2

.net ×1

entity-framework-core ×1

sql ×1