实体框架-“不允许新事务,因为会话中还有其他线程正在运行”

2023-12-31

我在尝试保存实体框架中的更改时收到以下错误 -

System.Data.SqlClient.SqlException:不允许新事务,因为会话中还有其他线程正在运行。

我已经看到了这个问题的各种答案,但我似乎无法让它们中的任何一个工作,基本上我在存储库内的事务中保存大量项目,我必须循环遍历几个项目来删除它们并编写一个审计记录。

我为此看到的所有其他答案(例如马克·斯塔福德回答 https://stackoverflow.com/questions/2113498/sqlexception-from-entity-framework-new-transaction-is-not-allowed-because-ther)建议声明一个显式事务(我有)或仅在完成循环后调用保存更改(由于当前审计的工作方式,这不是一个选项 - 需要审计 ID 来写入审计详细信息记录)。

每当在删除方法内调用“SaveChanges”时都会引发错误,请参见下文 -

public virtual void Save(DoseReturn oldDoseReturn)
{
    // Get the datetime when the save started
    DateTime saveStartTime = DateTime.Now;
    Dictionary<string, object> oldValues = new Dictionary<string, object>();
    Dictionary<string, object> newValues = new Dictionary<string, object>();

    // Get the object context and open a new transaction
    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
    objectContext.Connection.Open();
    DbTransaction transaction = objectContext.Connection.BeginTransaction();

    // Use the transaction for all updates
    using (transaction)
    {
        if (oldDoseReturn != null)
        {
              IDoseReturnStatusRepository statusRepository = new DoseReturnStatusRepository();
              var list = statusRepository.AsQueryable().Where(x => x.DoseReturnID == oldDoseReturn.DoseReturnID);

              foreach (var item in list)
              {
                  statusRepository.Delete(item, objectRetrievedDateTime, objectContext, saveStartTime, out oldValues, out newValues);
              }

              context.SaveChanges();

              // Get the relevant repository
              IDoseReturnsRepository repository = new DoseReturnsRepository();

              // audit and delete the object
              repository.Delete(oldDoseReturn, objectRetrievedDateTime, objectContext, saveStartTime, out oldValues, out newValues);

              context.SaveChanges();
         }
    }

    try
    {
         // Conduct a final save, then commit the transaction
         context.SaveChanges();
         transaction.Commit();
    }
    catch (Exception ex)
    {
         // An error has occurred, rollback the transaction and close the connection, then present the error
         transaction.Rollback();
         objectContext.Connection.Close();
         throw ex;
    }
    // Close the connection
    objectContext.Connection.Close();
}

public virtual void Delete(T entity, DateTime? objectRetrievedDateTime, ObjectContext objectContext, DateTime saveStartTime, out Dictionary<string, object> oldValues, out Dictionary<string, object> newValues)
    {
        oldValues = new Dictionary<string, object>();
        newValues = new Dictionary<string, object>();

        if (entity == null)
        {
            throw new ArgumentException("Cannot update a null entity.");
        }

        string entityName = entity.GetType().Name;

        if (!objectRetrievedDateTime.HasValue || !this.AuditsAfterRetieval(objectRetrievedDateTime, entityName, entity, saveStartTime))
        {
            this.DeletedEntityAudit(entity, out oldValues, out newValues);

            context.Entry(entity).State = System.Data.EntityState.Deleted;
            this.context.Set<T>().Remove(entity);
            this.Audit(entity, entityName, "Delete", oldValues, newValues, true);
            this.context.SaveChanges();
        }
        else
        {
            throw new Exception("Object cannot be saved as it has been amended in another thread");
        }
    }

这可能是因为您在尝试保存更改时正在枚举结果。

尝试改变这一行:

var list = statusRepository.AsQueryable()
               .Where(x => x.DoseReturnID == oldDoseReturn.DoseReturnID);

to:

var list = statusRepository.AsQueryable()
               .Where(x => x.DoseReturnID == oldDoseReturn.DoseReturnID)
               .ToList();

作为旁注调用.SaveChanges()在循环内部通常不是一个好主意,因为它通常是一个昂贵的操作(与数据库对话)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架-“不允许新事务,因为会话中还有其他线程正在运行” 的相关文章

随机推荐

Powered by Hwhale