c# - 存储库模式和更改日志实现

标签 c# asp.net-core repository-pattern

我有使用 .net core 2 构建的 API,我正在尝试实现更改日志功能。

我已经完成了基本部分,但我不确定这是否是最好的方法。

这是我的 EntityBaseRepository

public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IFullAuditedEntity, new()
{
    private readonly ApplicationContext context;

    public EntityBaseRepository(ApplicationContext context)
    {
        this.context = context;
    }

    public virtual IEnumerable<T> items => context.Set<T>().AsEnumerable().OrderByDescending(m => m.Id);

    public virtual T this[int id] => context.Set<T>().FirstOrDefault(m => m.Id == id);

    public virtual T GetSingle(int id) => context.Set<T>().FirstOrDefault(x => x.Id == id);

    public virtual T Add(T entity) => Operations(entity: entity, state: EntityState.Added);

    public virtual T Update(T entity) => Operations(entity: entity, state: EntityState.Modified);

    public virtual T Delete(T entity) => Operations(entity: entity, state: EntityState.Deleted);

    public virtual T Operations(T entity, EntityState state)
    {
        EntityEntry dbEntityEntry = context.Entry<T>(entity);

        if (state == EntityState.Added)
        {
            entity.CreationDateTime = DateTime.UtcNow;
            entity.CreationUserId = 1;

            context.Set<T>().Add(entity);
            dbEntityEntry.State = EntityState.Added;
        }
        else if (state == EntityState.Modified)
        {
            entity.LastModificationDateTime = DateTime.UtcNow;
            entity.LastModificationUserId = 1;

            var local = context.Set<T>().Local.FirstOrDefault(entry => entry.Id.Equals(entity.Id));
            if (local != null)
            {
                context.Entry(local).State = EntityState.Detached;
            }

            dbEntityEntry.State = EntityState.Modified;
        }
        else if (state == EntityState.Deleted)
        {
            entity.DeletionFlag = true;
            entity.DeletionUserId = 1;
            entity.DeletionDateTime = DateTime.UtcNow;

            dbEntityEntry.State = EntityState.Modified;
        }

        return entity;
    }

这是我的 Controller 之一。

[Produces("application/json")]
[Route("api/Item")]
public class ItemController : Controller
{
    private readonly IItemRepository repository;
    private readonly IChangeLogRepository changeLogRepository;
    private readonly IMapper mapper;

    public ItemController(IItemRepository repository, IChangeLogRepository _changeLogRepository, IMapper mapper)
    {
        this.repository = repository;
        this.changeLogRepository = _changeLogRepository;
        this.mapper = mapper;
    }

    [HttpPost]
    public IActionResult Post([FromBody]ItemDto transactionItemDto)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var item = repository.Add(mapper.Map<ItemDto, Item>(source: transactionItemDto));
        repository.Commit();

        ChangeLog log = new ChangeLog()
        {
            Log = "New Item Added"
        };

        changeLogRepository.Add(log);
        changeLogRepository.Commit();

        return new OkObjectResult(mapper.Map<Item, ItemDto>(source: item));
    }
}

如果您在 Controller 中看到,我添加了一项并提交了它,然后我为该插入准备了日志,添加并提交了它。

现在,我有几个问题,比如

  1. 我必须提交我的事务两次,有什么方法可以优化它吗?我不知道我是否可以在 EntityBaseRepository 上处理它。
  2. 我还想检查每个属性,是否有更改。 如果它发生变化,我想记录下来。处理它的最佳方法是什么?

如果有人能帮我解决这个问题就太好了。万分感激。谢谢。

最佳答案

您可以对更新日志使用 Action 过滤器,例如

using System;

public class TrackMyChange : IActionFilter
{
    private readonly string _chengeMessage;
    private readonly IChangeLogRepository _changeLogRepository;
    public TrackMyChange(string changeMessage,IChangeLogRepository changeLogRepository)
    {
        this._changeLogRepository = changeLogRepository;
        this._chengeMessage = chengeMessage;
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
    // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        ChangeLog log = new ChangeLog()
        {Log = this._chengeMessage};
        changeLogRepository.Add(log);
        changeLogRepository.Commit();
    }
}

在你的 Controller 中,你可以在你想要记录的操作之前使用它

[TrackMyChange("Your change log here")]
public IActionResult Post()
{
}

引用: Action Filter Attributes in .NET core

关于c# - 存储库模式和更改日志实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58258048/

相关文章:

c# - 使用 Kudu 在 Azure 上部署 ASP.NET vNext beta 2

c# - MVC 通用存储库/工作单元模式 - 扩展存储库

抽象方法的 PHP 类型提示实现 - 存储库模式

c# - 将代码备份到云端

c# - 使用 AngularJS 的 Web API 异步方法

c# - 如何在目标阈值内简化图像停止运动

c# - Actor 后的对象类型?

git - 我的 Azure 更改未发布到我的网站上

angular - 使用 Angular 2 和服务器 ASP.NET 核心获取错误 "JSONP injected script did not invoke callback."

c# - 摆脱通用声明