首页 > 解决方案 > EF Core - 自动设置字段值

问题描述

我正在使用ASP.NET Core + Entity Framework Core开发一个 Web 应用程序。

我想存储有关创建修改删除的更多信息。

我的 EF 实体实现了带来以下字段的接口:

我一直在尝试让我的应用程序自动设置所有字段。

现在我只能处理以下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 来处理它。谁能想到任何服务层级别的解决方案?或者也许有更好的方法?

标签: c#asp.netentity-frameworkrefactoringentity-framework-core

解决方案


此处的 UserId 和 TenantId 只是您的存储库服务(此处为 DbContext)所需的数据。如果一个服务需要数据,它应该被注入到服务中。

如果没有 DI,您可能会在 DbContext 上创建 UserID 和 TenantID 构造函数参数。使用 DI,您可以注入对提供此数据的服务的依赖。


推荐阅读