ServiceStack.OrmLite中是否可以使用拦截器?

The*_*ert 1 c# servicestack ormlite-servicestack

我想在OrmLite中为数据库插入或更新创建一个钩子.

假设我想CreateDate为每个插入数据库的记录写一个a,LastUpdateDate为没有数据库触发器的每个更新写一个或类似的东西.我看不出这样做,如果我打电话的方式Db.Save<Anything>(anyList)anyList包含新增和更改的对象.

我知道NHibernate确实提供了拦截器,以便在每个对象被持久化之前为其注入自定义逻辑.有没有办法在ServiceStack.OrmLite中实现这一点?

myt*_*thz 6

我认为这是一个很好的功能,所以我刚刚添加了对OrmLite的插入和更新过滤器的支持.现在,您可以使用以下命令配置全局更新或插入过滤器:

public interface IAudit
{
    DateTime CreatedDate { get; set; }
    DateTime ModifiedDate { get; set; }
    string ModifiedBy { get; set; }
}

OrmLiteConfig.InsertFilter = (dbCmd, row) =>
{
    var auditRow = row as IAudit;
    if (auditRow != null)
    {
        auditRow.CreatedDate = auditRow.ModifiedDate = DateTime.UtcNow;
    }
};

OrmLiteConfig.UpdateFilter = (dbCmd, row) =>
{
    var auditRow = row as IAudit;
    if (auditRow != null)
    {
        auditRow.ModifiedDate = DateTime.UtcNow;
    }
};
Run Code Online (Sandbox Code Playgroud)

因此,现在创建和修改日期字段将在实现的每一行上更新,IAudit并插入任何OrmLite的Typed API(即不是动态SQL或使用anon类型的部分更新),例如:

表定义

public class AuditTableA : IAudit
{
    [AutoIncrement]
    public int Id { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string ModifiedBy { get; set; }
}

public class AuditTableB : IAudit
{
    [AutoIncrement]
    public int Id { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string ModifiedBy { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

var a = new AuditTableA();
var b = new AuditTableB();
db.Save(a);
db.Save(b);

var insertRowA = db.SingleById<AuditTableA>(a.Id);
var insertRowB = db.SingleById<AuditTableB>(b.Id);

//both insertRowA/insertRowB CreatedDate/ModifiedDate fields populated
Run Code Online (Sandbox Code Playgroud)

验证

过滤器也可用于验证,其中抛出异常将阻止操作并阻止异常,例如:

OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = (dbCmd, row) =>
{
    var auditRow = row as IAudit;
    if (auditRow != null)
    {
        if (auditRow.ModifiedBy == null)
            throw new ArgumentNullException("ModifiedBy");
    }
};

try
{
    db.Insert(new AuditTableA());
}
catch (ArgumentNullException) {
   //throws ArgumentNullException
}

db.Insert(new AuditTableA { ModifiedBy = "Me!" }); //succeeds
Run Code Online (Sandbox Code Playgroud)

此功能现在可在ServiceStack的MyGet提要中使用,并将在NuGet 的下一个v4.0.11 +版本中提供.