В шаблоне asp.net нам необходимо отслеживать изменения в сущностях. Я вижу, что в ABP есть отслеживание сущностей (новое), но оно сохраняет все изменения сущностей в одной таблице, что нам не подходит. Можно ли создать пользовательский IEntityHistoryStore
для хранения этих изменений для каждого объекта (в их собственной таблице)?
Например, допустим, есть сущность Task
.
[Table("Task", Schema = "Tasks")]
public class Task : Entity<int>
{
[Column(TypeName = "varchar(255)")]
public string Description { get; set; }
// some more poco properties
}
Затем я хотел бы определить другую таблицу, zzLog.Tasks_Task, и я хотел бы, чтобы эта таблица выглядела так:
╔════════╦════════════════════════╦══════╦══════════╦════════════════════╗
║ TaskId ║ Description ║ lgId ║ lgAction ║ lgTime ║
╠════════╬════════════════════════╬══════╬══════════╬════════════════════╣
║ 1 ║ Some description ║ 1 ║ 1 ║ 2019-05-30 9:05 AM ║
║ 1 ║ Some other description ║ 2 ║ 2 ║ 2019-05-30 9:06 AM ║
║ 1 ║ Changed again ║ 3 ║ 2 ║ 2019-05-30 9:07 AM ║
║ 1 ║ Changed again ║ 4 ║ 3 ║ 2019-05-30 9:08 AM ║
╚════════╩════════════════════════╩══════╩══════════╩════════════════════╝
lgAction
— перечисление, 1 = создать, 2 = обновить, 3 = удалить
Это возможно? Инстинкт говорит нет, так как IEntityHistoryStore
, скорее всего, не может работать таким образом.
Да, из https://aspnetboilerplate.com/Pages/Documents/Entity-History#about-ientityhistorystore:
The Entity History tracking system uses
IEntityHistoryStore
to save change information. ... you can implement it in your own way ...
Реализовать MyEntityHistoryStore
:
public class MyEntityHistoryStore : IEntityHistoryStore
{
private readonly IRepository<zzLog.Tasks_Task> _taskLogRepository;
public EntityHistoryStore(IRepository<zzLog.Tasks_Task> taskLogRepository)
{
_taskLogRepository = taskLogRepository;
}
public virtual async Task SaveAsync(EntityChangeSet changeSet)
{
foreach (var entityChange in changeSet.EntityChanges)
{
var taskLog = new zzLog.Tasks_Task()
{
TaskId = entityChange.EntityId,
Description = entityChange.PropertyChanges
.Where(pc => pc.PropertyName == "Description")
.FirstOrDefault()?
.NewValue,
// lgId = 0, // Auto-increment
lgAction =
entityChange.ChangeType == EntityChangeType.Created ? 1 :
entityChange.ChangeType == EntityChangeType.Updated ? 2 :
entityChange.ChangeType == EntityChangeType.Deleted ? 3 : 0,
lgTime = entityChange.ChangeTime
};
await _taskLogRepository.InsertAsync(taskLog);
}
}
}
Замените сервис на IEntityHistoryStore
в методе PreInitialize
вашего модуля:
// using Abp.Configuration.Startup;
Configuration.ReplaceService<IEntityHistoryStore, MyEntityHistoryStore>(DependencyLifeStyle.Transient);
Отлично, это то, на что я надеялся.
Да, вы можете реализовать по-своему, как указано в документации: https://aspnetboilerplate.com/Pages/Documents/Entity-History#about-ientityhistorystore