|
|
|
@ -1,8 +1,10 @@
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
|
|
|
|
using Microsoft.EntityFrameworkCore.Metadata;
|
|
|
|
|
using Volo.Abp.Domain.Entities;
|
|
|
|
|
using Volo.Abp.Uow;
|
|
|
|
@ -30,26 +32,42 @@ namespace Volo.Abp.EntityFrameworkCore
|
|
|
|
|
|
|
|
|
|
public override int SaveChanges(bool acceptAllChangesOnSuccess)
|
|
|
|
|
{
|
|
|
|
|
ChangeTracker.DetectChanges();
|
|
|
|
|
ApplyAbpConcepts();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ChangeTracker.AutoDetectChangesEnabled = false;
|
|
|
|
|
return base.SaveChanges(acceptAllChangesOnSuccess);
|
|
|
|
|
}
|
|
|
|
|
catch (DbUpdateConcurrencyException ex)
|
|
|
|
|
{
|
|
|
|
|
throw new AbpDbConcurrencyException(ex.Message, ex);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
ChangeTracker.AutoDetectChangesEnabled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
|
|
|
|
|
{
|
|
|
|
|
ChangeTracker.DetectChanges();
|
|
|
|
|
ApplyAbpConcepts();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ChangeTracker.AutoDetectChangesEnabled = false;
|
|
|
|
|
return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
catch (DbUpdateConcurrencyException ex)
|
|
|
|
|
{
|
|
|
|
|
throw new AbpDbConcurrencyException(ex.Message, ex);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
ChangeTracker.AutoDetectChangesEnabled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void ConfigureConcurrencyStamp(IMutableEntityType entityType)
|
|
|
|
@ -64,5 +82,32 @@ namespace Volo.Abp.EntityFrameworkCore
|
|
|
|
|
.First(p => p.Name == nameof(IHasConcurrencyStamp.ConcurrencyStamp))
|
|
|
|
|
.IsConcurrencyToken = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void ApplyAbpConcepts()
|
|
|
|
|
{
|
|
|
|
|
/* Implement other concepts from ABP v1.x */
|
|
|
|
|
|
|
|
|
|
foreach (var entry in ChangeTracker.Entries())
|
|
|
|
|
{
|
|
|
|
|
switch (entry.State)
|
|
|
|
|
{
|
|
|
|
|
case EntityState.Modified:
|
|
|
|
|
case EntityState.Deleted:
|
|
|
|
|
HandleConcurrencyStamp(entry);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void HandleConcurrencyStamp(EntityEntry entry)
|
|
|
|
|
{
|
|
|
|
|
var entity = entry.Entity as IHasConcurrencyStamp;
|
|
|
|
|
if (entity == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entity.ConcurrencyStamp = Guid.NewGuid().ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|