与Nhibernate Session.Get和Session.CreateCriteria的区别

isu*_*anu 3 nhibernate soft-delete

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;
    }
Run Code Online (Sandbox Code Playgroud)

我们也覆盖了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);
    }
Run Code Online (Sandbox Code Playgroud)

现在,在某些上下文中,应用程序在softDeletable和可审计实体的Get方法中抛出了StackOverflow异常.经过一些调查后,我注意到它在PrepareEntityForUpdate/securityContextService.GetLoggedUser和我们的自定义存储库中的Get方法之间创建了一个循环.正如您所看到的,我已将注释限制为DeletedDate,这意味着Session.Get(id)应返回与创建条件相同的结果.但是,如果我通过this.Session.CreateCriteria(typeof(T))我得到StackOverflow异常,如果我评论这个并且只留下返回Session.Get(id)(不考虑deledate)一切正常.

这让我认为Session.Get和Session.CreateCriteria的工作方式不同.有任何想法吗?

Fre*_*els 6

Get将使用Session缓存.标准不会.

换句话说:Criteria将始终导致对DB的SQL查询/调用.获取不会总是导致SQL查询.如果NHibernate已经在会话中加载了一个实体,并且您希望使用Get再次检索该实体,NHibernate将返回它已从其缓存中加载的实体.