文章目录
概要
本次介绍的仓储IRepository的方法拓展,目的是为了让其方法自带操作日志记录的产生。需要记录值变化的操作基本是增、删、改的类型方法。
下面我们就这几个方法进行拓展。
一、 拓展的自定义步骤
1、创建拓展方法类
首先,你需要一个静态类用来包含你的拓展方法(静态)
public static class MkRepository
{
// 你的扩展方法将在这里定义
}
2、定义扩展方法
在 MkRepository类中定义你的扩展方法。
假设你要为 IRepository<TEntity, TKey> 添加一个 MkUpdateAsync方法,该方法记录发生变化的字段值并保存变更日志。
public static class MkRepository
{
public static async Task<bool> MkUpdateAsync<TEntity, TKey>(this IRepository<TEntity, TKey> repository, TEntity entity)
where TEntity : class, IEntity<TKey>
{
try
{
var entityDbContext = repository.GetDbContext();
var originalEntity = await entityDbContext.FindAsync(typeof(TEntity), entity.Id);
if (originalEntity == null)
{
throw new EntityNotFoundException(typeof(TEntity), entity.Id);
}
// 使用ChangeTracker来检测变更
entityDbContext.Entry(originalEntity).CurrentValues.SetValues(entity);
// 这里可以添加逻辑来记录哪些字段发生了变化
var changedProperties = entityDbContext.ChangeTracker.Entries<TEntity>()
.SelectMany(e => e.Properties.Where(p => p.IsModified))
.Where(e => e.CurrentValue != e.OriginalValue)
.Select(p =>
{
var propertyName = p.Metadata.Name;
var propertyInfo = typeof(TEntity).GetProperty(propertyName);
var displayNameAttr = propertyInfo?.GetCustomAttribute<DisplayAttribute>();
var displayName = displayNameAttr?.GetName() ?? propertyName; // 如果没有DisplayAttribute,则使用属性名
return $"{
displayName}从{
FormatValue(p.OriginalValue)}变为{
FormatValue(p.CurrentValue)};";
})
.ToList();
var result = await entityDbContext.SaveChangesAsync();
if (result > 0)
{
var changedPropertiesStr =