I would like to create a hook for database inserts or updates in OrmLite.
Lets say I want to write a CreateDate
for every record which is inserted to the database and a LastUpdateDate
for every update without database triggers or anything like that. I see no way of doing this if I call Db.Save<Anything>(anyList)
with anyList
containing new and changed objects.
I know that NHibernate does provide interceptors to inject custom logic for each object before it gets persisted. Is there any way to achieve this in ServiceStack.OrmLite?
I thought this was a good feature that was missing so I've just added support for Insert and Update Filters to OrmLite . So now you can configure a global Update or Insert filter with:
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;
}
};
So now the Created and Modified date fields will be updated on every row that implements IAudit
and is inserted in any of OrmLite's Typed APIs (ie not dynamic SQL or partial updates using anon types), eg:
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
The filters can also be used for validation where throwing an exception will prevent the operation and bubble the exception, eg:
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
This feature is now available in ServiceStack's MyGet feed and will be available in the next v4.0.11+ release on NuGet.
There isn't any way to achieve this in ServiceStack.OrmLite. That functionality is typical only of the heavier ORMs such as NHibernate, like you suggested.
ServiceStack.OrmLite is intended to be very lightweight, and as such provides a minimal API .
You can use an ORM such as NHibernate with ServiceStack. I personally use an ORM called LightSpeed from Mindscape in my ServiceStack projects, it can automatically take care of creation and update timestamps without any code hooks. Using the ServiceStack REST platform doesn't dictate that you have to use the ServiceStack ORM, if it isn't suitable.
As @Mythz suggests, you can request that this feature is added .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.