我正在使用Ayende的方法(http://ayende.com/Blog/archive/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.aspx)来设置具有监听器的实体的创建和更新日期,但它只为受影响的实体设置它们,而不是为工作单元中的任何其他设置。
所以,例如,如果我这样做:
Order order = repository.Get<Order>(1);
order.AddNote(new Note("this is a note"));
repository.SaveOrUpdate(order);
Note会获取创建/更新日期,但订单不会。是否有任何技巧可以让整个工作单元显示更新?或者我是否必须更新订单上的属性以设置更新日期?
如果它有任何区别,我也使用S#arp架构。
这是我正在使用的代码块:
public class AuditEventListener : IPreUpdateEventListener, IPreInsertEventListener
{
public bool OnPreUpdate(PreUpdateEvent @event)
{
var audit = @event.Entity as AuditedEntity;
if (audit == null)
return false;
var time = DateTime.Now;
Set(@event.Persister, @event.State, "UpdateDate", time);
audit.UpdateDate = time;
return false;
}
public bool OnPreInsert(PreInsertEvent @event)
{
var audit = @event.Entity as AuditedEntity;
if (audit == null)
return false;
var time = DateTime.Now;
Set(@event.Persister, @event.State, "CreateDate", time);
Set(@event.Persister, @event.State, "UpdatedDate", time);
audit.CreateDate= time;
audit.UpdateDate= time;
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 :(得分:2)
如果我没有弄错并且Notes集合是反向的,order
不是脏的,这就是为什么它没有被保存,因此没有触发PreUpdate事件。
所以是的......如果你想强制更新,你将不得不“触摸”订单。
答案 1 :(得分:0)
所以,迭戈是正确的,必须触及订单才能更新。我最终做的是将IBelongToOrder接口添加到订单中的任何内容中:
public interface IBelongToOrder
{
Order Order { get; set; }
}
然后,订单上的所有集合都实现了此接口。最后,OnPreInsert / Update刚刚检查了此接口并相应更新,如:
var orderChild = @event.Entity as IBelongToOrder;
if (orderChild != null)
{
orderChild.Order.UpdateDate = DateTime.Now;
}
希望这有助于其他人试图找出如何在一个工作单元中更新集合......