В этой главе мы рассмотрим механизм запроса критериев. API NHibernate Query by Criteria позволяет создавать запросы, манипулируя объектами критериев во время выполнения.
-
Этот подход позволяет динамически задавать ограничения без прямых манипуляций со строками, но он не теряет большую часть гибкости или мощи HQL.
-
С другой стороны, запросы, выраженные в качестве критериев, часто менее читабельны, чем запросы, выраженные в HQL.
-
Классический синтаксис критериев — это объектный API запросов, как показано в следующей программе.
Этот подход позволяет динамически задавать ограничения без прямых манипуляций со строками, но он не теряет большую часть гибкости или мощи HQL.
С другой стороны, запросы, выраженные в качестве критериев, часто менее читабельны, чем запросы, выраженные в HQL.
Классический синтаксис критериев — это объектный API запросов, как показано в следующей программе.
var customers = session.CreateCriteria<Customer>().Add(Restrictions.Like("FirstName", "H%"));
-
Как видите, мы выполняем критерии создания сеанса для клиента, и теперь мы добавляем объект ограничения в этот запрос.
-
Это полезно для страниц запросов, где пользователи могут выбирать определенные параметры, но не другие.
-
Проще создать запрос в виде древовидной структуры запроса, чем в HQL или LINQ, где вы можете использовать оператор AND или OR в предложении WHERE.
-
Проще просто добавить дополнительные ограничения, используя эти критерии объектов.
Как видите, мы выполняем критерии создания сеанса для клиента, и теперь мы добавляем объект ограничения в этот запрос.
Это полезно для страниц запросов, где пользователи могут выбирать определенные параметры, но не другие.
Проще создать запрос в виде древовидной структуры запроса, чем в HQL или LINQ, где вы можете использовать оператор AND или OR в предложении WHERE.
Проще просто добавить дополнительные ограничения, используя эти критерии объектов.
Давайте рассмотрим простой пример, в котором мы создадим запрос и получим доступ к API критериев через createCriteria, а затем добавим ограничение на то, что имя начинается с H.
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.CreateCriteria<Customer>() .Add(Restrictions.Like("FirstName", "H%")); foreach (var customer in customers.List<Customer>()) { 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; } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующий вывод.
Herman Crooks (4ead3480-6bce-11e1-b15c-6cf049ee52be) Points: 74 HasGoldStatus: True MemberSince: 12/3/2010 12:00:00 AM (Utc) CreditRating: Neutral AverageRating: 0 Orders: Order Id: 4ead3480-6bce-11e1-b15d-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b15e-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b15f-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b160-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b161-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b162-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b163-6cf049ee52be Hudson Bins (4ec03f80-6bce-11e1-b2b7-6cf049ee52be) Points: 56 HasGoldStatus: False MemberSince: 10/20/2008 12:00:00 AM (Utc) CreditRating: Terrible AverageRating: 0 Orders: Order Id: 4ec03f80-6bce-11e1-b2b8-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2b9-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2ba-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bb-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bc-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bd-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2be-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bf-6cf049ee52be Hettie Feest (4ec50240-6bce-11e1-b300-6cf049ee52be) Points: 82 HasGoldStatus: False MemberSince: 4/10/2009 12:00:00 AM (Utc) CreditRating: Neutral AverageRating: 0 Orders: Order Id: 4ec50240-6bce-11e1-b301-6cf049ee52be Order Id: 4ec50240-6bce-11e1-b302-6cf049ee52be Order Id: 4ec50240-6bce-11e1-b303-6cf049ee52be Press <ENTER> to exit…
Давайте посмотрим на еще один простой пример, в котором мы будем извлекать клиента, имя которого равно «Лаверне»
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.CreateCriteria<Customer>() .Add(Restrictions.Eq("FirstName", "Laverne")) .List<Customer>(); foreach (var customer in customers) { 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...
Теперь одним из основных недостатков критериев API являются непрозрачные строки в именах свойств. Таким образом, если имя было реорганизовано как что-то другое, инструмент рефакторинга не обязательно обнаружит непрозрачную строку.