Nhibernate Session.Get和Session.CreateCriteria之间的区别是什么?Nhibernate Session.Get和Session.CreateCriteria之间的区别
我的故事是:
在我们的产品,我们通过增加一个接口ISoftDeletable,每一个实现该接口具有deletedDate和deletedBy领域类实现的softDeletion。我们还有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;
}
同样,我们也overrided的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的工作方式不同。 任何想法?
这不是个好主意,因为Where子句每次都会执行,但在某些情况下可能需要显示已删除的实体e.q.显示历史记录项目日志,您需要显示用户以太网所做的所有操作,如果删除或不删除,则不显示。我通过Filters实现了这一点。这允许我在需要时启用或禁用软删除的过滤器。不幸的是,过滤器不适用于获取/加载。 – isuruceanu 2011-09-12 14:15:25