【发布时间】:2019-02-06 23:53:36
【问题描述】:
我正在使用 ASP.NET Core + Entity Framework Core 开发一个 Web 应用程序。
我想存储更多关于创建、修改和删除的信息。
我的 EF 实体实现了带有以下字段的接口:
DateTime CreationTime { get; set; }long? CreatorUserId { get; set; }DateTime? ModificationTime { get; set; }long? ModifierUserId { get; set; }DateTime? DeletionTime { get; set; }public long? DeleterUserId { get; set; }bool IsDeleted { get; set; }int TenantId { get; set; }
我一直在尝试让我的应用自动设置所有字段。
现在我只能处理DateTime 字段:
AppDbContext.cs
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
ChangeTracker.DetectChanges();
ChangeTracker.ProcessModifiedTime();
ChangeTracker.ProcessSoftDelete();
ChangeTracker.ProcessCreationTime();
return (await base.SaveChangesAsync(true, cancellationToken));
}
ChangeTrackerExtensions.cs
public static class ChangeTrackerExtensions
{
public static void ProcessCreationTime(this ChangeTracker changeTracker)
{
foreach (var item in changeTracker.Entries<ICreationTime>().Where(e => e.State == EntityState.Added))
{
item.CurrentValues[AppConsts.CreationTime] = DateTime.Now;
}
}
public static void ProcessModifiedTime(this ChangeTracker changeTracker)
{
foreach (var item in changeTracker.Entries<IModificationTime>().Where(e => e.State == EntityState.Modified))
{
item.CurrentValues[AppConsts.ModificationTime] = DateTime.Now;
}
}
public static void ProcessSoftDelete(this ChangeTracker changeTracker)
{
foreach (var item in changeTracker.Entries<ISoftDelete>().Where(e => e.State == EntityState.Deleted))
{
item.State = EntityState.Modified;
item.CurrentValues[AppConsts.IsDeleted] = true;
item.CurrentValues[AppConsts.DeletionTime] = DateTime.Now;
}
}
}
在服务层或控制器级别,每次都可以分配所需的值(CreatorUserId、MofidierUserId、DeleterUserId)但这变成例行任务,非常乏味。
我见过AspNetBoilerplate implementation,但让我担心的是开发人员让他们的 DbContext 依赖于 Session 和其他东西。
public abstract class AbpDbContext : DbContext, ITransientDependency, IShouldInitialize
{
public IAbpSession AbpSession { get; set; }
public IEntityChangeEventHelper EntityChangeEventHelper { get; set; }
public ILogger Logger { get; set; }
public IEventBus EventBus { get; set; }
public IGuidGenerator GuidGenerator { get; set; }
public ICurrentUnitOfWorkProvider CurrentUnitOfWorkProvider { get; set; }
public IMultiTenancyConfig MultiTenancyConfig { get; set; }
...
恕我直言,这是典型的违反单一职责原则。
我尝试查看 interceptors,但它们似乎仅在 Entity Framework 的普通(非核心)版本中可用 - 仍然没有设法让我了解如何实现我上面提到的。
真的,我完全不知道如何使用 Entity Framework Core 处理它。谁能想到任何服务层级别的解决方案?或者也许有更好的方法?
【问题讨论】:
标签: c# asp.net entity-framework refactoring entity-framework-core