В этой главе мы рассмотрим QueryOver Queries. Это новый синтаксис, который больше похож на LINQ с использованием синтаксиса цепочки методов, как показано в следующем запросе.
var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "Laverne");
-
Это все еще критерии под прикрытием, но теперь наши запросы строго типизированы.
-
Как мы видели в запросе критериев, первое имя — просто непрозрачная строка, теперь мы на самом деле используем x.FirstName , поэтому первое имя подвергается рефакторингу и переименовывается, что изменяется в запросе критериев стиля ссылки, используя запрос через ,
-
Мы все еще можем делать много подобных вещей, но вы не можете использовать синтаксис понимания запроса с запросом поверх, вы должны использовать синтаксис цепочки методов, и вы не можете смешивать и сопоставлять ссылку и критерии.
-
Для многих запросов запрос через API очень полезен и обеспечивает гораздо более простое понимание синтаксиса объекта, чем непосредственное использование критериев.
Это все еще критерии под прикрытием, но теперь наши запросы строго типизированы.
Как мы видели в запросе критериев, первое имя — просто непрозрачная строка, теперь мы на самом деле используем x.FirstName , поэтому первое имя подвергается рефакторингу и переименовывается, что изменяется в запросе критериев стиля ссылки, используя запрос через ,
Мы все еще можем делать много подобных вещей, но вы не можете использовать синтаксис понимания запроса с запросом поверх, вы должны использовать синтаксис цепочки методов, и вы не можете смешивать и сопоставлять ссылку и критерии.
Для многих запросов запрос через API очень полезен и обеспечивает гораздо более простое понимание синтаксиса объекта, чем непосредственное использование критериев.
Давайте рассмотрим простой пример, в котором мы будем извлекать клиента, чье имя Лаверн, используя запрос.
using System; using System.Data; using System.Linq; using System.Reflection; using HibernatingRhinos.Profiler.Appender.NHibernate; using NHibernate.Cfg; using NHibernate.Criterion; using NHibernate.Dialect; using NHibernate.Driver; using NHibernate.Linq; namespace NHibernateDemo { internal class Program { private static void Main() { var cfg = ConfigureNHibernate(); var sessionFactory = cfg.BuildSessionFactory(); using(var session = sessionFactory.OpenSession()) using(var tx = session.BeginTransaction()) { var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "Laverne"); foreach (var customer in customers.List()) { Console.WriteLine(customer); } tx.Commit(); } Console.WriteLine("Press <ENTER> to exit..."); Console.ReadLine(); } private static Configuration ConfigureNHibernate() { NHibernateProfiler.Initialize(); var cfg = new Configuration(); cfg.DataBaseIntegration(x => { x.ConnectionStringName = "default"; x.Driver<SqlClientDriver>(); x.Dialect<MsSql2008Dialect>(); x.IsolationLevel = IsolationLevel.RepeatableRead; x.Timeout = 10; x.BatchSize = 10; }); cfg.SessionFactory().GenerateStatistics(); cfg.AddAssembly(Assembly.GetExecutingAssembly()); return cfg; } } }
Как вы можете видеть, это все еще Критерии под прикрытием, но это просто более хороший синтаксис.
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующий вывод.
Laverne Hegmann (4e97c816-6bce-11e1-b095-6cf049ee52be) Points: 74 HasGoldStatus: True MemberSince: 4/4/2009 12:00:00 AM (Utc) CreditRating: Neutral AverageRating: 0 Orders: Order Id: 4ea14d96-6bce-11e1-b095-6cf049ee52be Order Id: 4ea14d96-6bce-11e1-b096-6cf049ee52be Order Id: 4ea14d96-6bce-11e1-b097-6cf049ee52be Order Id: 4ea14d96-6bce-11e1-b098-6cf049ee52be Press <ENTER> to exit...
Одним из недостатков является то, что, скажем, мы хотим сказать, что FirstName.StartsWith («A»), как показано в следующей программе.
var customers = session.QueryOver<Customer>() .Where(x => x.FirstName.StartsWith("A")); foreach (var customer in customers.List()) { Console.WriteLine(customer); } tx.Commit();
Теперь давайте снова запустим приложение, и вы увидите, что это не поставщик LINQ, поскольку он не знает, что такое метод StartsWith , поэтому вы получите исключение RunTime .
Исключение говорит нераспознанный вызов метода. Здесь мы делаем очевидную вещь, но это не обязательно работает.
Давайте попробуем что-нибудь еще, например FirstName равно «A%», как показано в следующем коде.
var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "A%"); foreach (var customer in customers.List()) { Console.WriteLine(customer); }
Давайте запустим это еще раз, и вы увидите, что мы не получим никаких результатов, как показано ниже.
Press <ENTER> to exit...
Чтобы понять, почему мы не получаем никаких результатов, давайте взглянем на профилировщик NHibernate.
Как видите, первое имя равно A%, а это не так. % Используется в SQL с использованием оператора like. Теперь нам нужно создать ограничение в предложении WHERE, как показано в следующей программе.
var customers = session.QueryOver<Customer>() .Where(Restrictions.On<Customer>(c => c.FirstName).IsLike("A%")); foreach (var customer in customers.List()) { Console.WriteLine(customer); }
Давайте снова запустим ваше приложение, и вы увидите, что все клиенты извлекаются с именем, начинающимся с A.
Alejandrin Will (4ea3aef6-6bce-11e1-b0b4-6cf049ee52be) Points: 24 HasGoldStatus: False MemberSince: 10/1/2011 12:00:00 AM (Utc) CreditRating: VeryVeryGood AverageRating: 0 Orders: Order Id: 4ea3aef6-6bce-11e1-b0b5-6cf049ee52be Austyn Nolan (4ea871b6-6bce-11e1-b110-6cf049ee52be) Points: 67 HasGoldStatus: True MemberSince: 12/29/2007 12:00:00 AM (Utc) CreditRating: Neutral AverageRating: 0 Orders: Order Id: 4ea871b6-6bce-11e1-b111-6cf049ee52be Antonia Murphy (4ea871b6-6bce-11e1-b121-6cf049ee52be) Points: 72 HasGoldStatus: True MemberSince: 6/15/2009 12:00:00 AM (Utc) CreditRating: Terrible AverageRating: 0 Orders: Order Id: 4ea871b6-6bce-11e1-b122-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b123-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b124-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b125-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b126-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b127-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b128-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b129-6cf049ee52be Order Id: 4ea871b6-6bce-11e1-b12a-6cf049ee52be
Он работает так же, как и раньше, за исключением использования нового синтаксиса QueryOver . Многие разработчики считают, что синтаксис LINQ более доступен и часто делает правильные вещи.
Если LINQ не может справиться с этим, тогда вы начнете смотреть на HQL или Критерии, чтобы увидеть, будет ли это более подходящим.
Он просто дает вам другой синтаксис, поэтому Criteria, и критерии создания, и QueryOver предоставляют вам еще один механизм запросов, который позволяет извлекать данные из базы данных с помощью NHibernate.