Nhibernate Session.Get 和 Session.CreateCriteria 有什么区别?
我的故事是:
在我们的产品中,我们通过添加接口 ISoftDeletable 来实现 softDeletion,实现该接口的每个类都有 deletedDate 和 deletedBy 字段。我们还有 AuditableEntity 类,这意味着实现它的每个类都有:createdDate、createdBy、modifiedDate、modifiedBy。
以下是来源:
public class SaveUpdateEventListener : DefaultSaveEventListener
{
private readonly ISecurityContextService securityContextService;
public SaveUpdateEventListener(ISecurityContextService securityContextService)
{
this.securityContextService = securityContextService;
}
protected override object PerformSaveOrUpdate(SaveOrUpdateEvent @event)
{
this.PrepareAuditableEntity(@event);
return base.PerformSaveOrUpdate(@event);
}
private void PrepareAuditableEntity(SaveOrUpdateEvent @event)
{
var entity = @event.Entity as AuditableEntity;
if (entity == null)
{
return;
}
if (this.securityContextService.EdiPrincipal == null)
{
throw new Exception("No logged user.");
}
if (entity.Id == 0)
{
this.ProcessEntityForInsert(entity);
}
else
{
this.ProcessEntityForUpdate(entity);
}
}
private void ProcessEntityForUpdate(AuditableEntity entity)
{
entity.ModifiedBy = securityContextService.GetLoggedUser();
entity.ModifiedDate = DateTime.Now;
}
private void ProcessEntityForInsert(AuditableEntity entity)
{
entity.CreatedBy = securityContextService.GetLoggedUser();
entity.CreatedDate = DateTime.Now;
}
我们还覆盖了 Session.Get 方法。
public virtual T Get(long id)
{
if (typeof(ISoftDeletable).IsAssignableFrom(typeof(T)))
{
return
this.Session.CreateCriteria(typeof(T))
.Add(Restrictions.Eq("Id", id))
//.Add(Restrictions.IsNull("DeletedDate"))
.UniqueResult<T>();
}
return Session.Get<T>(id);
}
现在,在某些上下文中,应用程序在 softDeletable 和可审计实体的 Get 方法中引发了 StackOverflow 异常。经过一番调查,我注意到它在 PrepareEntityForUpdate/securityContextService.GetLoggedUser 和来自我们自定义存储库的 Get 方法之间创建了一个循环。正如你所看到的,我已经评论了 DeletedDate 的限制,这意味着 Session.Get(id) 应该返回与创建的条件相同的结果。但是如果我通过 this.Session.CreateCriteria(typeof(T)) 我得到 StackOverflow 异常,如果我评论这个并且只留下返回 Session.Get(id) (不考虑删除日期)一切正常。
这让我认为 Session.Get 和 Session.CreateCriteria 的工作方式不同。有任何想法吗?