首页 > 解决方案 > 是否可以扩展 IEntityHistoryStore 以存储每个表而不是在同一个表中跟踪所有内容?

问题描述

在 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可能无法以这种方式工作。

标签: asp.netentity-frameworkentity-framework-coreasp.net-boilerplate

解决方案


是的,来自https://aspnetboilerplate.com/Pages/Documents/Entity-History#about-ientityhistorystore

实体历史跟踪系统用于IEntityHistoryStore保存更改信息。...您可以以自己的方式实现它...

实施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);

推荐阅读