小巧玲珑的控制日期

Dapper control dates

这个问题旨在让大家了解一下使用 Dapper 控制日期时间。

这些控件用于审核数据存储中的信息并确定特定行的创建/更新时间。我无法在 Whosebug 中找到有关 GitHub's 项目的任何信息,所以我希望这个 post 成为帮助他人的中心事实来源,甚至变成未来的扩展图书馆。

任何答案、资源或最佳实践将不胜感激。

我 运行 遇到过一个案例,在这个案例中,我正在使用一个被 Rails 和 Dapper 使用的数据库。 Rails 正在管理 created_at 和 updated_at,而不是数据库。因此,对于 .net 应用程序,我必须实施一个解决方案来管理这些并提供在这些层添加额外业务逻辑(例如事件)的能力。

我已经包含了一个基本示例,说明我如何使用围绕 Dapper Simple Crud 的包装器处理此问题以进行插入和更新。此示例不包括从 dapper 和 simplecrud 公开其他关键方法,例如 Query、GET、Delete 等。您需要自行决定公开这些方法。

为了安全起见,请确保使用属性 [Dapper.IgnoreUpdate]

装饰模型 created_at 属性
[Table("examples")]
public partial class example
{
    [Key]
    public virtual int id { get; set; }
    [Required(AllowEmptyStrings = false)]
    [StringLength(36)]
    public virtual string name { get; set; }
    [Dapper.IgnoreUpdate]
    public virtual DateTime created_at { get; set; }
    public virtual DateTime updated_at { get; set; }
}

public class ExampleRepository : IExampleRepository
{
    private readonly IYourDapperWrapper db;

    public PartnerRepository(IYourDapperWrapper yourDapperWrapper){
        if (yourDapperWrapper == null) throw new ArgumentNullException(nameof(yourDapperWrapper));
        db = yourDapperWrapper;
    }

    public void Update(example exampleObj)
    {
      db.Update(exampleObj);
    }

    public example Create(example exampleObj)
    {
      var result = db.Insert(exampleObj);
      if (result.HasValue) exampleObj.id = result.value;
      return exampleObj;
    }
}

public class YourDapperWrapper : IYourDapperWrapper
{
    private IDbConnectionFactory db;

    public YourDapperWrapper(IDbConnectionFactory dbConnectionFactory){
      if (dbConnectionFactory == null) throw new ArgumentNullException(nameof(dbConnectionFactory));
      db = dbConnectionFactory;
    }

    public int Insert(object model, IDbTransaction transaction = null, int? commandTimeout = null)
    {
      DateUpdate(model, true);
      var results = Db.NewConnection().Insert(model, transaction, commandTimeout);
      if (!results.HasValue || results == 0) throw new DataException("Failed to insert object.");
      return results;
    }

    public int Update(object model, IDbTransaction transaction = null, int? commandTimeout = null)
    {
      DateUpdate(model, false);
      var results = Db.NewConnection().Update(model, transaction, commandTimeout);
      if (!results.HasValue || results == 0) throw new DataException("Failed to update object.");     
      return results;
    }

    private void DateUpdate(object model, bool isInsert)
    {
      model.GetType().GetProperty("updated_at")?.SetValue(model, DateTime.UtcNow, null);
      if (isInsert) model.GetType().GetProperty("created_at")?.SetValue(model, DateTime.UtcNow, null);
    }
}