我想在OrmLite中为数据库插入或更新创建一个钩子。
假设我想为插入数据库的每条记录写一个CreateDate
,为没有数据库触发器的任何更新写一个LastUpdateDate
或类似的东西。如果我使用包含新对象和更改对象的Db.Save<Anything>(anyList)
来调用anyList
,我认为无法执行此操作。
我知道NHibernate does provide interceptors在每个对象被持久化之前为其注入自定义逻辑。有没有办法在ServiceStack.OrmLite中实现这一点?
答案 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。
您可以使用NHM的ORM和ServiceStack。我个人在我的ServiceStack项目中使用一个名为LightSpeed from Mindscape的ORM,它可以自动处理创建和更新时间戳,而无需任何代码挂钩。使用ServiceStack REST平台并不表示如果不合适,您必须使用ServiceStack ORM。
正如@Mythz建议的那样,你可以request that this feature is added。