c# - EF Core - 自动设置字段值
问题描述
我正在使用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; }
...
恕我直言,这是对单一责任原则的典型违反。
我尝试研究拦截器,但它们似乎仅在实体框架的普通(非核心)版本中可用- 仍然没有设法了解如何实现我上面提到的内容。
真的,我完全不知道如何使用 Entity Framework Core 来处理它。谁能想到任何服务层级别的解决方案?或者也许有更好的方法?
解决方案
此处的 UserId 和 TenantId 只是您的存储库服务(此处为 DbContext)所需的数据。如果一个服务需要数据,它应该被注入到服务中。
如果没有 DI,您可能会在 DbContext 上创建 UserID 和 TenantID 构造函数参数。使用 DI,您可以注入对提供此数据的服务的依赖。
推荐阅读
- android - React Native:Info.plist 和 AndroidManifest.xml 从哪里提取变量值?
- django - 当我通过基本身份验证在邮递员中使用 PUT 方法时出现错误,我正在研究 django rest-framework
- java - maven-surefire-plugin 升级到 springboot-starter-parent:2.1.8.RELEASE 后崩溃
- python - 如何在 if 参数中使用 tkinter 中的 Entry 函数?
- spring-mvc - Spring MVC 没有找到映射
- g1ant - 在字典中拆分类似于ini文件的文本
- css - Squarespace 在同一线上的等距锚链接
- c# - 使用 Entity Framework Core 在主键违规视图上显示自定义错误
- android - 从 viewPager 片段中获取用户输入信息 (Kotlin)
- nginx - real_ip_header 似乎没有改变客户端 IP