EF Core - автоматически устанавливать значения полей - PullRequest
0 голосов
/ 01 сентября 2018

Я занимаюсь разработкой веб-приложения с использованием ASP.NET Core + Entity Framework Core .

Я хотел бы хранить больше информации относительно создания , модификации & удаления .

В моих сущностях 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;
        }
    }
}

На уровне Service Layer или Controller можно каждый раз назначать требуемое значение (CreatorUserId, MofidierUserId, DeleterUserId), но это становится процедурой задание, очень утомительно .

Я видел реализацию AspNetBoilerplate , но меня беспокоит то, что разработчики делают свой 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 - до сих пор не удалось разобраться как реализовать то, что я упомянул выше.

Действительно, я совершенно заблудился в том, как справиться с этим с помощью Entity Framework Core. Кто-нибудь может придумать какое-либо решение уровня сервисного уровня для этого? Или, может быть, есть лучший способ?

1 Ответ

0 голосов
/ 01 сентября 2018

UserId и TenantId - это просто фрагменты данных, которые необходимы вашей службе репозитория (здесь DbContext). Если службе нужны данные, их следует внедрить в службу.

Без DI вы можете задать параметры конструктора UserID и TenantID для вашего DbContext. С помощью DI вы можете внедрить зависимость от службы, предоставляющей эти данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...