В этой главе мы рассмотрим, как использовать собственные запросы 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-запроса для извлечения данных из базы данных.