- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在查看了 NHibernate.Envers
代码后,我意识到我实现了错误的接口(interface)。现在我知道使用什么接口(interface)可以更好地工作了。
我目前的实现是这样的:
public class PreCollectionUpdate : IPreCollectionUpdateEventListener
{
public void OnPreUpdateCollection(PreCollectionUpdateEvent @event)
{
var collectionEntry = @event.Session.PersistenceContext.GetCollectionEntry(@event.Collection);
if(!collectionEntry.LoadedPersister.IsInverse)
return;
var collection = @event.Collection;
var collectionEntries = collection.Entries(collectionEntry.LoadedPersister);
foreach(var entry in collectionEntries)
{
if(!(entry is TrackableEntity))
return;
var trackableEntity = entry as TrackableEntity;
trackableEntity.AddedAt = Time.Now;
trackableEntity.AddedBy = User.Current;
}
}
}
通过调试我可以看到它正在被调用并正确修改我的集合。然而,出于某种原因,它首先将项目插入我的集合中,并为 AddedAt
和 AddedBy
设置默认值,然后执行更新以填充所述值。
这是我的测试代码:
using (var transaction = Session.BeginTransaction())
{
var locate = new Locate
{
TicketNumber = 123456789,
Status = Status.InProgress
};
Session.Save(locate);
transaction.Commit();
}
using (var transaction = Session.BeginTransaction())
{
var locate1 = Session.Get<Locate>(1);
locate1.AddReview(new AllClear());
Session.Save(locate1);
transaction.Commit();
}
using (var transaction = Session.BeginTransaction())
{
var locate1 = Session.Load<Locate>(1);
transaction.Commit();
}
这是为什么?
调试我的测试我可以看到,在我提交事务后,AddedBy
和 AddedWhen
属性都已正确填充。只是不确定为什么它不提交修改后的集合。
在我的代码中添加一堆 Console.Write
语句,我可以看到我的事件监听器在我提交 session 后 被调用。
NHibernate: INSERT INTO Locates (AddedAt, AddedBy, TicketNumber, Status, SomeOtherField) VALUES (@p0, @p1, @p2, @p3, @p4); select last_insert_rowid();@p0 = 1/1/0001 00:00:00 [Type: DateTime (0)], @p1 = NULL [Type: String (0)], @p2 = 123456789 [Type: Int64 (0)], @p3 = 'InProgress' [Type: String (0)], @p4 = NULL [Type: String (0)]
Saving review...
Commiting...
NHibernate: INSERT INTO "Review" (AddedAt, AddedBy, Locate_id) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 1/1/0001 00:00:00 [Type: DateTime (0)], @p1 = NULL [Type: String (0)], @p2 = NULL [Type: Int32 (0)]
In event listener...
Completed filling auditable properties.
我也试过从 IFlushEntityEventListener
继承,但同样的问题发生了。我在没有将 AddedAt
和 AddedBy
属性保存到数据库的情况下提交。然而,我的对象会改变,所以下次我使用所述对象时,NHibernate 会发现它是脏的,并向数据库发出更新命令。我想要的是在初始提交时提交 AddedAt
和 AddedBy
属性。
如果我不清楚,请告诉我。
最佳答案
我不相信您可以使用 PreUpdateCollectionEventListener 来完成您想做的事情。 PreUpdateEventListeners 在 nhibernate 管道中运行得非常晚,因此在事件被抛出时,NHibernate 已经将实体的状态序列化到内存中。您需要同时更改状态和实体本身,但是在 PreUpdateCollectionEvent 中,据我所知,您无权访问状态:
public class AuditEventListener : IPreUpdateEventListener
{
public bool OnPreUpdate(PreUpdateEvent @event)
{
// Grab the entity from the event
var trackableEntity = @event.Entity as TrackableEntity;
if ( trackableEntity == null)
return false;
// Set the state for the entity (needed to write new values to the db)
Set(@event.Persister, @event.State, "AddedAt", time);
Set(@event.Persister, @event.State, "AddedByBy", name);
// Set the entity values (needed to keep your session in sync)
trackableEntity.AddedAt = Time.Now;
trackableEntity.AddedBy = User.Current;
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
}
附言。我知道我曾经读过 Ayende 关于此的一篇非常好的文章,但我现在找不到了。
关于nhibernate - 为什么 `PreCollectionUpdateEvent`不插入修改后的集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9067925/
在查看了 NHibernate.Envers 代码后,我意识到我实现了错误的接口(interface)。现在我知道使用什么接口(interface)可以更好地工作了。 我目前的实现是这样的: publ
我是一名优秀的程序员,十分优秀!