Разница между Nhibernate Session.Get и Session.Критерии создания
-
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 к сгенерированному запросу.