2016-05-12 6 views
3

Я хотел бы найти разницу в использовании этих трех способов получения данных из базы данных, когда делает что-то вроде:разница между NHibernate Query <T>, получить <T> и загрузить <T>

public T GetById(int id) { 
    using (var db = Database.Session) { 
     using (var t = db.BeginTransaction()) { 
      try { 
       return db.Get<T>(id); 
      } 
      catch (Exception) { 
       if (!t.WasCommitted) { 
        t.Rollback(); 
       } 
       throw; 
      } 
     } 
    } 
} 

или

public T GetById(int id) { 
    using (var db = Database.Session) { 
     using (var t = db.BeginTransaction()) { 
      try { 
       return Query<T>().First(x=>x.Id == id); 
       //or something like 
       //return Query<T>().Where(x=>x.Id == id).FirstOrDefault(); 
       //or 
       //return QueryOver<T>().Where(x=>x.Id == id).FirstOrDefault; 
      } 
      catch (Exception) { 
       if (!t.WasCommitted) { 
        t.Rollback(); 
       } 
       throw; 
      } 
     } 
    } 
} 

или даже так:

public T GetById(int id) { 
    using (var db = Database.Session) { 
     using (var t = db.BeginTransaction()) { 
      try { 
       return db.Load<T>(id); 
      } 
      catch (Exception) { 
       if (!t.WasCommitted) { 
        t.Rollback(); 
       } 
       throw; 
      } 
     } 
    } 
} 

И добавив еще один вопрос к этому, как Query() отличается от QueryOver()?

Я прочитал несколько ответов здесь, в stackoverflow, но поскольку большинство из них было посвящено началу использования Linq и NHibernate 3, я хотел бы знать, как выглядит этот сценарий сегодня.

+0

Может быть, [это] (https://ayende.com/blog/3988/nhibernate-the-difference-between- get-load-and-query-by-id) может вам помочь? – SeM

ответ

2

Похожие try to explain it is here

В целом у нас есть три способа, как получить экземпляр из БД по идентификатору.

1) Запрос. Здесь мы используем QueryOver API (родной язык NHibernate) или Query (реализация API MS LINQ). Эти запросы всегда попадают в БД (или кэш) и могут загрузить полный корневой объект, получать какое-то отношение, или быть просто проекции (только несколько столбцов/свойства преобразуются в некоторый DTO)

2) Тогда мы имеем Get<TEntity>(), который был предназначен как наиболее распространенный способ получения элемента по идентификатору. Он всегда попадет DB, потому что его контракта говорит (get):

Возвращения упорной экземпляры данного класса сущностей с указанным идентификатором, или нуля, если нет такого настойчивого экземпляра

Таким образом, чтобы быть уверенным, что объект существует или нет, необходимо удалить БД.

3) Наконец, существует третий договор - Load<TEntity>().Он никогда не ударит DB, чтобы проверить, есть ли такой пункт (с обеспеченными ID): load():

Возвращения упорной экземпляр данного класса объекта с данным идентификатором, при условии, что экземпляр существует.

Если у нас есть идентификатор ссылки, и мы знаем, что он существует, мы должны использовать Load<TEntity>().

Это просто создать прокси - с обеспеченными ID и при вставке или обновлении этого корня/держателя объекта, прокси-ID будет использоваться для создания правильного инструкции SQL.

Резюме:Get() и Load() есть для нас по причине. Они были разработаны для поддержки различных сценариев.

Смотрите также:

1

Как Query() отличается от QueryOver()?

QueryOver является строго типизированным вариантом критериев и более NHibernate специфичны. Практически все, что вы можете сделать в ICriteria, можно выполнить с помощью QueryOver. В золотые дни ICriteria NH2 вам всегда приходилось бросать, поэтому именно поэтому теперь вам нужно бросить в конце цепи обратно в int.

LINQ (запрос) стандартный метод запроса, который работает на IQueryable, который не нуждается в явных ссылок на NHibernate и можно считать более ORM агностик и поэтому соответствует стандарту Linq. Как вы правильно указали, вам не нужно бросать в int, поскольку вы выбираете в результате customNumber.

Смежные вопросы