nhibernate - Nhibernate Session.Get 和 Session.CreateCriteria 之间的区别

标签 nhibernate soft-delete

Nhibernate Session.Get 和 Session.CreateCriteria 有什么区别?

我的故事是:

在我们的产品中,我们通过添加接口(interface) ISoftDeletable 来实现软删除,每个实现此接口(interface)的类都有 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 异常,如果我评论这个异常并且只留下 return Session.Get(id) (不考虑删除日期)一切正常。

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

最佳答案

Get 将使用 Session 缓存。 条件不会。

换句话说:Criteria 将始终导致对数据库的 SQL 查询/调用。 Get 并不总是会导致 sql 查询。如果 NHibernate 已经在 session 中加载了一个实体,而您想使用 Get 再次检索该实体,NHibernate 将返回它已经从其缓存中加载的实体。

关于nhibernate - Nhibernate Session.Get 和 Session.CreateCriteria 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1973510/

相关文章:

c# - 错误映射 NHibernate 3.3

laravel - 保存时软删除 Eloquent 模型

软删除前的MySQL检查

c# - Fluent nhibernate 一对一映射

c# - 如何使用 FluentNHibernate 映射具有复杂键类型 (CultureInfo) 的字典

c# - NHibernate 搜索 - 多个 Web 服务器

ios - 使用 Core Data 和服务器同步实现软删除或存档的最佳方式

php - 模型上的 SoftDeletes 会破坏动态属性

azure - 查找 Azure 存储中软删除 blob 的永久删除日期

Nhibernate 查询结束