Я занимаюсь разработкой веб-приложения с использованием 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. Кто-нибудь может придумать какое-либо решение уровня сервисного уровня для этого? Или, может быть, есть лучший способ?