使用 System.Transaction 如何更新实体框架中的多行

Har*_*ngi 5 c# sql-server entity-framework asp.net-core

我想使用System.Transactions和更新多行。我的数据库是使用实体框架连接的。

下面是我试过的代码,但它抛出了一个错误:

public  void Update(List<PortfolioCompanyLinkModel> record)
{
    var transaction = _context.Database.BeginTransaction();

    try
    {
        foreach (var item in record)
        {
            var portfolioCompanyLink = _context.PortfolioCompanyLink.FirstOrDefault(p => p.Id == item.Id);
            portfolioCompanyLink.ModifiedBy = _loggedInUser;
            portfolioCompanyLink.ModifiedOn = DateTime.UtcNow;
            portfolioCompanyLink.URL = item.URL;

            _context.SaveChanges();
            //_context.PortfolioCompanyLink.Update(portfolioCompanyLink);
        }

        transaction.Commit();
    }
    catch(Exception ex) 
    {
        transaction.Rollback();
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:

配置的执行策略“SqlServerRetryingExecutionStrategy”不支持用户发起的事务。使用'DbContext.Database.CreateExecutionStrategy()'返回的执行策略将事务中的所有操作作为一个可重试的单元来执行。

有人可以帮助我如何处理这个问题吗?

Ath*_*ras 11

你的问题是SqlServerRetryingExecutionStrategy 微软文档中描述的

使用重试执行策略时,您可以将多个操作包装在单个事务中。例如,以下代码在单个事务中包装了两个 SaveChanges 调用。如果任一操作的任何部分失败,则不会应用任何更改。

关于弹性的 MS 文档

System.InvalidOperationException:配置的执行策略“SqlServerRetryingExecutionStrategy”不支持用户发起的事务。使用'DbContext.Database.CreateExecutionStrategy()'返回的执行策略将事务中的所有操作作为一个可重试的单元来执行。

解决方案:手动调用执行策略

var executionStrategy = _context.db.CreateExecutionStrategy();

executionStrategy.Execute(
    () =>
    {
        // execute your logic here
        using(var transaction = _context.Database.BeginTransaction()) 
        {
            try
            {
                foreach (var item in record)
                {
                    var portfolioCompanyLink = _context.PortfolioCompanyLink.FirstOrDefault(p => p.Id == item.Id);
                    portfolioCompanyLink.ModifiedBy = _loggedInUser;
                    portfolioCompanyLink.ModifiedOn = DateTime.UtcNow;
                    portfolioCompanyLink.URL = item.URL;
                    _context.SaveChanges();
                    //_context.PortfolioCompanyLink.Update(portfolioCompanyLink);
                }

                transaction.Commit();
            }
            catch(Exception ex) {
                transaction.Rollback();
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

您也可以全局设置策略,但这取决于您要实现的目标。