Разница между Nhibernate Session.Get и Session.Критерии создания

StackOverflow https://stackoverflow.com/questions/1973510

  •  21-09-2019
  •  | 
  •  

Вопрос

В чем разница между Nhibernate Session.Get и Session.createCriteria?

Моя история такова:

В нашем продукте мы реализовали softDeletion, добавив интерфейс ISoftDeletable, каждый класс, реализующий этот интерфейс, имеет поля DeletedDate и deletedBy.Также у нас есть класс AuditableEntity, который означает, что каждый класс, который его реализует, имеет:Дата создания, CreatedBy, Измененная дата, 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;
    }

Также мы переопределили сеанс.Метод 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);
    }

Теперь в некотором контексте приложение выдало исключение StackOverflow в методах Get для объекта softDeletable и auditable.После некоторого расследования я отметил, что это создает цикл между PrepareEntityForUpdate / securityContextService.GetLoggedUser и Get method из нашего пользовательского репозитория.Как вы можете видеть, я прокомментировал ограничение на DeletedDate, это означает, что Session.Get (id) должен возвращать тот же результат, что и созданные критерии.Но если я пройду через это.Сеанс.createCriteria(typeof(T)) Я получу исключение StackOverflow, если я прокомментирую это и оставлю только return Session .Get (id) (без учета даты удаления) все работает нормально.

Это заставляет меня думать, что Session.Get и Session.createCriteria работают по-разному.Есть какие-нибудь идеи?

Это было полезно?

Решение

Get будет использовать кеш сеанса.Критериев не будет.

Другими словами:Критерии всегда будут приводить к SQL-запросу / вызову базы данных.Get не всегда приводит к sql-запросу.Если объект уже был загружен NHibernate в сеансе, и вы хотите снова извлечь объект с помощью Get, NHibernate вернет объект, который он уже загрузил из своего кэша.

Другие советы

В дополнение к этому вы можете установить параметр where в классе mapping.Там вы можете добавить:"Дата удаления РАВНА НУЛЮ".Когда выполняется Get, NHibernate добавляет этот оператор WHERE к сгенерированному запросу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top