添加项目文件。
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using IM.DomainCommons;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace IM.Infrastructure.Efcore
|
||||
{
|
||||
public class BaseDbContext : DbContext
|
||||
{
|
||||
private IMediator? mediator;
|
||||
|
||||
public BaseDbContext(DbContextOptions options, IMediator mediator)
|
||||
: base(options)
|
||||
{
|
||||
this.mediator = mediator;
|
||||
}
|
||||
|
||||
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (mediator != null)
|
||||
{
|
||||
await mediator.DispatchDomainEventsAsync(this);
|
||||
}
|
||||
|
||||
var softDeletedEntities = ChangeTracker
|
||||
.Entries<ISoftDelete>()
|
||||
.Where(x => x.State == EntityState.Modified && x.Entity.IsDeleted)
|
||||
.ToList();
|
||||
|
||||
|
||||
var result = await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||||
|
||||
softDeletedEntities.ForEach(e => e.State = EntityState.Detached);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using IM.DomainCommons;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace IM.Infrastructure.Efcore
|
||||
{
|
||||
public static class EfcoreExtension
|
||||
{
|
||||
public static void EnableSoftDeletionGlobalFilter(this ModelBuilder modelBuilder)
|
||||
{
|
||||
var entityTypesHasSoftDeletion = modelBuilder.Model.GetEntityTypes()
|
||||
.Where(e => e.ClrType.IsAssignableTo(typeof(ISoftDelete)));
|
||||
|
||||
foreach (var entityType in entityTypesHasSoftDeletion)
|
||||
{
|
||||
var isDeletedProperty = entityType.FindProperty(nameof(ISoftDelete.IsDeleted));
|
||||
var parameter = Expression.Parameter(entityType.ClrType, "p");
|
||||
var filter = Expression.Lambda(Expression.Not(Expression.Property(parameter, isDeletedProperty.PropertyInfo)), parameter);
|
||||
entityType.SetQueryFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
public static IQueryable<T> Query<T>(this DbContext context) where T : class
|
||||
{
|
||||
return context.Set<T>().AsNoTracking();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using IM.DomainCommons;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace IM.Infrastructure.Efcore
|
||||
{
|
||||
public static class MediatorExtensions
|
||||
{
|
||||
public static async Task DispatchDomainEventsAsync(this IMediator mediator, DbContext db)
|
||||
{
|
||||
var domainEntities = db.ChangeTracker
|
||||
.Entries<IDomainEvents>()
|
||||
.Where(x => x.Entity.GetDomainEvents().Any());
|
||||
|
||||
var domainEvents = domainEntities
|
||||
.SelectMany(s => s.Entity.GetDomainEvents())
|
||||
.ToList();
|
||||
|
||||
domainEntities.ToList().ForEach(e =>
|
||||
{
|
||||
e.Entity.ClearDomainEvents();
|
||||
});
|
||||
|
||||
foreach (var domainEvent in domainEvents)
|
||||
{
|
||||
await mediator.Publish(domainEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
global using System.Linq;
|
||||
global using System.Threading.Tasks;
|
||||
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MediatR" Version="14.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DomainCommons\IM.DomainCommons.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user