В этой главе мы рассмотрим, как использовать собственные запросы SQL в NHibernate. Если вы использовали рукописный SQL в течение ряда лет, вы можете быть обеспокоены тем, что ORM лишит вас той выразительности и гибкости, к которым вы привыкли.
-
Мощные средства запросов NHibernate позволяют вам делать практически все, что вы делаете в SQL, а в некоторых случаях и больше.
-
В тех редких случаях, когда вы не можете заставить собственные средства запросов NHibernate делать именно то, что вы хотите.
-
NHibernate позволяет вам извлекать объекты, используя собственный диалект SQL вашей базы данных.
Мощные средства запросов NHibernate позволяют вам делать практически все, что вы делаете в SQL, а в некоторых случаях и больше.
В тех редких случаях, когда вы не можете заставить собственные средства запросов NHibernate делать именно то, что вы хотите.
NHibernate позволяет вам извлекать объекты, используя собственный диалект SQL вашей базы данных.
Давайте рассмотрим простой пример запросов Native SQL в NHibernate.
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; using NHibernate; 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()) { IQuery sqlQuery = session.CreateSQLQuery("SELECT * FROM CUSTOMER").AddEntity(typeof(Customer)); var customers = sqlQuery.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; } } }
Приведенный выше пример использует CreateSQLQuery () для получения списка объектов, и вы также заметите, что корневой тип сущности, который вы хотите, чтобы запрос возвращал, указан как Customer.
Запустим ваше приложение, и вы увидите, что все клиенты извлекаются из базы данных.
Emerson Prosacco (4ec2a0e0-6bce-11e1-b2cf-6cf049ee52be)
Points: 17
HasGoldStatus: False
MemberSince: 6/22/2007 12:00:00 AM (Utc)
CreditRating: Excellent
AverageRating: 0
Orders:
Order Id: 4ec2a0e0-6bce-11e1-b2d0-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2d1-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2d2-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2d3-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2d4-6cf049ee52be
Kaci Friesen (4ec2a0e0-6bce-11e1-b2d5-6cf049ee52be)
Points: 30
HasGoldStatus: True
MemberSince: 5/25/2007 12:00:00 AM (Utc)
CreditRating: VeryVeryGood
AverageRating: 0
Orders:
Order Id: 4ec2a0e0-6bce-11e1-b2d6-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2d7-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2d8-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2d9-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2da-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2db-6cf049ee52be
Eveline Waters (4ec2a0e0-6bce-11e1-b2dc-6cf049ee52be)
Points: 58
HasGoldStatus: False
MemberSince: 10/29/2009 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 0
Orders:
Order Id: 4ec2a0e0-6bce-11e1-b2dd-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2de-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2df-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2e0-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2e2-6cf049ee52be
Molly Kuhn (4ec2a0e0-6bce-11e1-b2e3-6cf049ee52be)
Points: 73
HasGoldStatus: False
MemberSince: 12/16/2007 12:00:00 AM (Utc)
CreditRating: VeryGood
AverageRating: 0
Orders:
Order Id: 4ec2a0e0-6bce-11e1-b2e4-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2e5-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2e6-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2e7-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2e8-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2e9-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2ea-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2eb-6cf049ee52be
Order Id: 4ec2a0e0-6bce-11e1-b2ec-6cf049ee52be
Вот еще один способ написания собственного SQL-запроса, как показано ниже.
IList<Customer> customers = session.CreateSQLQuery("SELECT * FROM CUSTOMER") .AddScalar("Id", NHibernateUtil.Guid) .AddScalar("FirstName", NHibernateUtil.String) .AddScalar("LastName", NHibernateUtil.String) .List<Customer>();
-
Как видно из вышеприведенного запроса, указана строка запроса SQL, а также столбцы и типы для возврата.
-
Это вернет массивы IList of Object со скалярными значениями для каждого столбца в таблице Customer.
-
Будут возвращены только эти три столбца, даже если запрос использует * и может вернуть больше трех перечисленных столбцов.
Как видно из вышеприведенного запроса, указана строка запроса SQL, а также столбцы и типы для возврата.
Это вернет массивы IList of Object со скалярными значениями для каждого столбца в таблице Customer.
Будут возвращены только эти три столбца, даже если запрос использует * и может вернуть больше трех перечисленных столбцов.
Давайте посмотрим на другой простой пример.
IList<Customer> customers = session.CreateSQLQuery("SELECT * FROM CUSTOMER WHERE FirstName = 'Laverne'") .AddEntity(typeof(Customer)) .List<Customer>(); foreach (var customer in customers) { Console.WriteLine(customer); }
Давайте снова запустим ваше приложение, и вы увидите следующий результат.
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...
Точно так же вы можете указать любой тип SQL-запроса для извлечения данных из базы данных.