我在PreSaveEventListener中使用NHibernate OnPreInsert和OnPreUpdate事件来设置我的实体的CreatedDate和ModifiedDate。问题是,有两个实体在我第一次创建时会触发两个事件。 这会导致问题,因为在OnPreInsert事件后实体状态不会被保存,因此OnPreUpdate事件在一个全新的实体状态下运行,而我的CreatedDate永远不会被设置为(默认为01/01 / 0001)。
起初,我认为这是因为我的代码在事务结束之前重新启动了两个SaveOrUpdate调用。果然,我发现了一些这样的代码。但后来我意识到这仍然发生在另一个实体身上。据我所知,只有这两个实体有这个问题。我通过在其构造函数中设置CreatedDate来暂时解决问题,但我想避免这种情况。
这是我的结构:
业务实体(具有两个具体连接子类的抽象类)
BusinessContact实体与业务的多对一关系
编辑:我最近意识到它也发生在另一个对象(InvoiceLineItem)上,但不是几乎相同的对象(BillLineItem)以几乎相同的方式实例化和使用。似乎相当随意。
以前有人见过这个吗?
这是事件监听器代码:
public class PreSaveEventListener : IPreInsertEventListener, IPreUpdateEventListener {
public bool OnPreInsert(PreInsertEvent @event) {
EntityWithGuidId entity = @event.Entity as EntityWithGuidId;
if (null != entity) {
var createdDate = DateTime.Now;
var modifiedDate= DateTime.Now;
Set(@event.Persister, @event.State, "CreatedDate", createdDate);
Set(@event.Persister, @event.State, "ModifiedDate", modifiedDate);
entity.CreatedDate = createdDate;
entity.ModifiedDate = modifiedDate;
}
return false;
}
public bool OnPreUpdate(PreUpdateEvent @event) {
EntityWithGuidId entity = @event.Entity as EntityWithGuidId;
if (null != entity) {
var modifiedDate= DateTime.Now;
Set(@event.Persister, @event.State, "ModifiedDate", modifiedDate);
entity.ModifiedDate = modifiedDate;
}
return false;
}
private void Set(IEntityPersister persister, object[] state, string propertyName, object value) {
var index = Array.IndexOf(persister.PropertyNames, propertyName);
if (index == -1)
return;
state[index] = value;
}
}
答案 0 :(得分:0)
事件监听器在我的项目中引起了很多不同的问题,其中许多对我来说没有意义。我认为你的问题可能是因为NHibernate在创建后真正更新了你的实体。 NHibernate可以更新实体版本或为它设置一些id(或guid)。你能在这里放置已发行实体的映射吗?我还建议你在profiler中查看sql查询。
答案 1 :(得分:0)
我实际上碰到了这个问题,可能会出现同样的问题。
我实现了自己的StringTrimEnd
类型处理程序,它在插入数据库之前或检索它们之后修剪了字符串的结尾。
好吧,我实现了Equals
方法错误,当x和y为null时,它为Equals(object x, object y)
返回false。
因此,当我创建一个带有空字符串的新对象时,它将加载的值(null)与当前值(null)进行比较,并确定需要更新(以及插入)。
也许这会在某些时候帮助某人。
答案 2 :(得分:0)
您在DB中有可空字段,但在NH
中未标记为可为空