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

时间:2014-02-15 21:40:54

标签: c# servicestack ormlite-servicestack

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

假设我想为插入数据库的每条记录写一个CreateDate,为没有数据库触发器的任何更新写一个LastUpdateDate或类似的东西。如果我使用包含新对象和更改对象的Db.Save<Anything>(anyList)来调用anyList,我认为无法执行此操作。

我知道NHibernate does provide interceptors在每个对象被持久化之前为其注入自定义逻辑。有没有办法在ServiceStack.OrmLite中实现这一点?

2 个答案:

答案 0 :(得分:6)

我认为这是一个很好的功能,所以我只是added support for Insert and Update Filters to 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;
    }
};

现在,创建和修改日期字段将在实现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; }
}

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

验证

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

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

此功能现已在ServiceStack's MyGet feed中提供,并将在NuGet的下一个 v4.0.11 + 版本中提供。

答案 1 :(得分:1)

在ServiceStack.OrmLite中没有任何方法可以实现这一点。正如您所建议的那样,该功能仅适用于较重的ORM,例如NHibernate。

ServiceStack.OrmLite旨在非常轻量级,因此provides a minimal API

API

您可以使用NHM的ORM和ServiceStack。我个人在我的ServiceStack项目中使用一个名为LightSpeed from Mindscape的ORM,它可以自动处理创建和更新时间戳,而无需任何代码挂钩。使用ServiceStack REST平台并不表示如果不合适,您必须使用ServiceStack ORM。


正如@Mythz建议的那样,你可以request that this feature is added