首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EF核集字段值自动

EF核集字段值自动
EN

Stack Overflow用户
提问于 2018-09-01 01:04:18
回答 1查看 1.1K关注 0票数 0

我正在使用ASP.NET Core + Entity Framework 开发一个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; }

我一直在努力使我的应用程序设置所有的字段automatically.

现在,我只能处理DateTime字段:

AppDbContext.cs

代码语言:javascript
复制
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

代码语言:javascript
复制
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;
        }
    }
}

在服务层或控制器级别,每次都可以分配所需的值(CreatorUserIdMofidierUserIdDeleterUserId),但这成为一项常规任务,非常繁琐的

我看过AspNetBoilerplate实现,但让我担心的是,开发人员使他们的DbContext依赖于会话和其他东西。

代码语言:javascript
复制
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; }
    ...

IMHO,这是典型的违反单一责任原则

我试着研究拦截器,但它们似乎只在实体框架的普通(非核心)版本中可用--仍然没有设法让我了解如何实现上面提到的内容。

真的,我完全不知道如何用实体框架核心来处理它。有人能想到任何服务层级别的解决方案吗?或者有更好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-01 02:53:16

这里的UserId和TenantId只是您的存储库服务(这里是DbContext)所需的数据片段。如果服务需要数据,则应该将其注入服务。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52124080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档