/// <summary> /// 异步地将此上下文中的所有更改保存到数据库中,同时自动开启事务或使用现有同连接事务 /// </summary> /// <remarks> /// <para> /// 此方法将自动调用 <see cref="M:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges" /> /// 若要在保存到基础数据库之前发现对实体实例的任何更改,请执行以下操作。这可以通过以下类型禁用 /// <see cref="P:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.AutoDetectChangesEnabled" />. /// </para> /// <para> /// 不支持同一上下文实例上的多个活动操作。请使用“等待”确保在此上下文上调用其他方法之前任何异步操作都已完成。 /// </para> /// </remarks> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param> /// <returns> /// 表示异步保存操作的任务。任务结果包含写入数据库的状态条目数。 /// </returns> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateException"> /// 保存到数据库时遇到错误。 /// </exception> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException"> /// 保存到数据库时会遇到并发冲突。 /// 当在保存期间影响到意外数量的行时,就会发生并发冲突。 /// 这通常是因为数据库中的数据在加载到内存后已经被修改。 /// </exception> public override async Task <int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { IList <AuditEntityEntry> auditEntities = new List <AuditEntityEntry>(); if (_osharpDbOptions.AuditEntityEnabled == true) { IAuditEntityProvider auditEntityProvider = _serviceProvider.GetService <IAuditEntityProvider>(); auditEntities = auditEntityProvider?.GetAuditEntities(this).ToList(); } //开启或使用现有事务 await BeginOrUseTransactionAsync(cancellationToken); int count = await base.SaveChangesAsync(cancellationToken); if (count > 0 && auditEntities?.Count > 0) { AuditEntityEventData eventData = new AuditEntityEventData(auditEntities); IEventBus eventBus = _serviceProvider.GetService <IEventBus>(); if (eventBus != null) { await eventBus.PublishAsync(this, eventData); } } return(count); }
public void AuditEntityEventDataTest() { var list = new List <AuditEntityEntry>() { new AuditEntityEntry() }; AuditEntityEventData eventData = new AuditEntityEventData(list); eventData.AuditEntities.ShouldNotBeNull(); eventData.AuditEntities.ShouldNotBeEmpty(); eventData.AuditEntities.First().ShouldBe(list[0]); }
/// <summary> /// 异步地将此上下文中的所有更改保存到数据库中,同时自动开启事务或使用现有同连接事务 /// </summary> /// <remarks> /// <para> /// 此方法将自动调用 <see cref="M:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges" /> /// 若要在保存到基础数据库之前发现对实体实例的任何更改,请执行以下操作。这可以通过以下类型禁用 /// <see cref="P:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.AutoDetectChangesEnabled" />. /// </para> /// <para> /// 不支持同一上下文实例上的多个活动操作。请使用“await”确保在此上下文上调用其他方法之前任何异步操作都已完成。 /// </para> /// </remarks> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param> /// <returns> /// 表示异步保存操作的任务。任务结果包含写入数据库的状态条目数。 /// </returns> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateException"> /// 保存到数据库时遇到错误。 /// </exception> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException"> /// 保存到数据库时会遇到并发冲突。 /// 当在保存期间影响到意外数量的行时,就会发生并发冲突。 /// 这通常是因为数据库中的数据在加载到内存后已经被修改。 /// </exception> public override async Task <int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { IList <AuditEntityEntry> auditEntities = new List <AuditEntityEntry>(); if (_osharpDbOptions.AuditEntityEnabled == true) { IAuditEntityProvider auditEntityProvider = _serviceProvider.GetService <IAuditEntityProvider>(); auditEntities = auditEntityProvider?.GetAuditEntities(this).ToList(); } //开启或使用现有事务 #if NET5_0_OR_GREATER await BeginOrUseTransactionAsync(cancellationToken); #else BeginOrUseTransaction(); #endif int count; try { count = await base.SaveChangesAsync(cancellationToken); } catch (Exception ex) { string msg = ex.Message; while (ex.InnerException != null) { msg += $"---{ex.InnerException.Message}"; ex = ex.InnerException; } Logger.LogDebug($"SaveChangesAsync 引发异常:{msg}"); throw; } if (count > 0 && auditEntities?.Count > 0) { AuditEntityEventData eventData = new AuditEntityEventData(auditEntities); IEventBus eventBus = _serviceProvider.GetService <IEventBus>(); if (eventBus != null) { await eventBus.PublishAsync(this, eventData); } } return(count); }
/// <summary> /// Saves all changes made in this context to the database. /// </summary> /// <remarks> /// This method will automatically call <see cref="M:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges" /> to discover any /// changes to entity instances before saving to the underlying database. This can be disabled via /// <see cref="P:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.AutoDetectChangesEnabled" />. /// </remarks> /// <returns> /// The number of state entries written to the database. /// </returns> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateException"> /// An error is encountered while saving to the database. /// </exception> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException"> /// A concurrency violation is encountered while saving to the database. /// A concurrency violation occurs when an unexpected number of rows are affected during save. /// This is usually because the data in the database has been modified since it was loaded into memory. /// </exception> public override int SaveChanges() { IList <AuditEntity> auditEntities = new List <AuditEntity>(); if (_osharpDbOptions != null && _osharpDbOptions.AuditEntityEnabled) { auditEntities = this.GetAuditEntities(); } int count = base.SaveChanges(); if (count > 0 && auditEntities.Count > 0) { AuditEntityEventData eventData = new AuditEntityEventData(auditEntities); IEventBus eventBus = ServiceLocator.Instance.GetService <IEventBus>(); eventBus.PublishSync(this, eventData); } return(count); }
/// <summary> /// Asynchronously saves all changes made in this context to the database. /// </summary> /// <remarks> /// <para> /// This method will automatically call <see cref="M:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges" /> to discover any /// changes to entity instances before saving to the underlying database. This can be disabled via /// <see cref="P:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.AutoDetectChangesEnabled" />. /// </para> /// <para> /// Multiple active operations on the same context instance are not supported. Use 'await' to ensure /// that any asynchronous operations have completed before calling another method on this context. /// </para> /// </remarks> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous save operation. The task result contains the /// number of state entries written to the database. /// </returns> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateException"> /// An error is encountered while saving to the database. /// </exception> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException"> /// A concurrency violation is encountered while saving to the database. /// A concurrency violation occurs when an unexpected number of rows are affected during save. /// This is usually because the data in the database has been modified since it was loaded into memory. /// </exception> public override async Task <int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { IList <AuditEntity> auditEntities = new List <AuditEntity>(); if (_osharpDbOptions != null && _osharpDbOptions.AuditEntityEnabled) { auditEntities = this.GetAuditEntities(); } int count = await base.SaveChangesAsync(cancellationToken); if (count > 0 && auditEntities.Count > 0) { AuditEntityEventData eventData = new AuditEntityEventData(auditEntities); IEventBus eventBus = ServiceLocator.Instance.GetService <IEventBus>(); await eventBus.PublishAsync(this, eventData); } return(count); }
/// <summary> /// 将在此上下文中所做的所有更改保存到数据库中,同时自动开启事务或使用现有同连接事务 /// </summary> /// <remarks> /// 此方法将自动调用 <see cref="M:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges" /> /// 若要在保存到基础数据库之前发现对实体实例的任何更改,请执行以下操作。这可以通过以下类型禁用 /// <see cref="P:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.AutoDetectChangesEnabled" />. /// </remarks> /// <returns> /// 写入数据库的状态项的数目。 /// </returns> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateException"> /// 保存到数据库时遇到错误。 /// </exception> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException"> /// 保存到数据库时会遇到并发冲突。 /// 当在保存期间影响到意外数量的行时,就会发生并发冲突。 /// 这通常是因为数据库中的数据在加载到内存后已经被修改。 /// </exception> public override int SaveChanges() { IList <AuditEntityEntry> auditEntities = new List <AuditEntityEntry>(); if (_osharpDbOptions != null && _osharpDbOptions.AuditEntityEnabled) { auditEntities = this.GetAuditEntities(); } //开启或使用现有事务 BeginOrUseTransaction(); int count = base.SaveChanges(); if (count > 0 && auditEntities.Count > 0) { AuditEntityEventData eventData = new AuditEntityEventData(auditEntities); IEventBus eventBus = this.GetService <IEventBus>(); eventBus.Publish(this, eventData); } return(count); }
/// <summary> /// 将在此上下文中所做的所有更改保存到数据库中,同时自动开启事务或使用现有同连接事务 /// </summary> /// <remarks> /// 此方法将自动调用 <see cref="M:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges" /> /// 若要在保存到基础数据库之前发现对实体实例的任何更改,请执行以下操作。这可以通过以下类型禁用 /// <see cref="P:Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.AutoDetectChangesEnabled" />. /// </remarks> /// <returns> /// 写入数据库的状态项的数目。 /// </returns> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateException"> /// 保存到数据库时遇到错误。 /// </exception> /// <exception cref="T:Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException"> /// 保存到数据库时会遇到并发冲突。 /// 当在保存期间影响到意外数量的行时,就会发生并发冲突。 /// 这通常是因为数据库中的数据在加载到内存后已经被修改。 /// </exception> public override int SaveChanges() { IList <AuditEntityEntry> auditEntities = new List <AuditEntityEntry>(); if (_osharpDbOptions.AuditEntityEnabled == true) { IAuditEntityProvider auditEntityProvider = _serviceProvider.GetService <IAuditEntityProvider>(); auditEntities = auditEntityProvider?.GetAuditEntities(this).ToList(); } //开启或使用现有事务 BeginOrUseTransaction(); int count = base.SaveChanges(); if (count > 0 && auditEntities?.Count > 0) { AuditEntityEventData eventData = new AuditEntityEventData(auditEntities); IEventBus eventBus = _serviceProvider.GetService <IEventBus>(); eventBus.Publish(this, eventData); } return(count); }