В этой главе мы рассмотрим, как работают функции загрузки и получения и как мы можем их использовать. Это два очень похожих API, предоставляемых ISession для загрузки объекта по первичному ключу.
-
Get — вернет объект или ноль.
-
Load — он вернет объект или сгенерирует исключение ObjectNotFoundException .
Get — вернет объект или ноль.
Load — он вернет объект или сгенерирует исключение ObjectNotFoundException .
Теперь, почему у нас есть эти два разных API?
нагрузка
-
Это потому, что Load может оптимизировать обходы базы данных намного эффективнее.
-
На самом деле Load возвращает прокси-объект и не нуждается в доступе к базе данных прямо при вызове этого вызова Load.
-
Когда вы обращаетесь к этому прокси, объект не попадает в базу данных, он может вызвать исключение ObjectNotFoundException в этой точке.
Это потому, что Load может оптимизировать обходы базы данных намного эффективнее.
На самом деле Load возвращает прокси-объект и не нуждается в доступе к базе данных прямо при вызове этого вызова Load.
Когда вы обращаетесь к этому прокси, объект не попадает в базу данных, он может вызвать исключение ObjectNotFoundException в этой точке.
Получить
-
И наоборот, с Get из-за ограничений CLR или Common Language Runtime и NHibernate должен немедленно перейти в базу данных, проверить, есть ли объекты, и вернуть ноль, если его нет.
-
У него нет опции объекта для отсрочки этого извлечения, обратного обращения к базе данных на более позднее время, потому что он не может вернуть прокси-объект, и это поменял этот прокси-объект на ноль, когда пользователь фактически обращается к нему.
И наоборот, с Get из-за ограничений CLR или Common Language Runtime и NHibernate должен немедленно перейти в базу данных, проверить, есть ли объекты, и вернуть ноль, если его нет.
У него нет опции объекта для отсрочки этого извлечения, обратного обращения к базе данных на более позднее время, потому что он не может вернуть прокси-объект, и это поменял этот прокси-объект на ноль, когда пользователь фактически обращается к нему.
Давайте рассмотрим простой пример, в котором вы увидите, как они на самом деле используются, и разницу между Get и Load. Мы продолжим работу с теми же классами домена Customers и Orders и аналогичными файлами сопоставления из предыдущей главы.
В этом примере мы сначала будем использовать Get, как показано в следующей программе.
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 id1 = Guid.Parse("4e97c816-6bce-11e1-b095-6cf049ee52be"); var id2 = Guid.Parse("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"); var customer1 = session.Get<Customer>(id1); Console.WriteLine("Customer1 data"); Console.WriteLine(customer1); var customer2 = session.Get<Customer>(id2); Console.WriteLine("Customer2 data"); Console.WriteLine(customer2); 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; } } }
Как вы можете видеть, у нас есть два идентификатора Guid , первый из которых является хорошим идентификатором, это идентификатор клиента, который, как мы знаем, находится в базе данных. Пока второго идентификатора нет в базе данных. Оба эти идентификатора передаются в качестве параметра в метод Get (), а затем результат выводится на консоль.
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующий вывод.
Customer1 data 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 Customer2 data Press <ENTER> to exit...
Как видно, данные Customer1 напечатаны, но данные Customer2 пусты, потому что запись Customer2 недоступна в базе данных.
Когда вы снова запустите свое приложение, мы можем вставить точку останова перед оператором фиксации, а затем посмотрим на обоих клиентов в окне Watch.
Как вы можете видеть, данные Customer1 доступны, а Customer2 имеет значение null, а тип NHibernateDemo.Customer для обоих.
Теперь давайте использовать метод Load вместо Get в том же примере, как показано в следующем коде.
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 id1 = Guid.Parse("4e97c816-6bce-11e1-b095-6cf049ee52be"); var id2 = Guid.Parse("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"); var customer1 = session.Load<Customer>(id1); Console.WriteLine("Customer1 data"); Console.WriteLine(customer1); var customer2 = session.Load<Customer>(id2); Console.WriteLine("Customer2 data"); Console.WriteLine(customer2); 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; } } }
Теперь давайте запустим этот пример, и вы увидите, что выдается следующее исключение, как показано на скриншоте.
Теперь, если вы посмотрите в окно Watch, вы увидите, что тип является прокси клиента для обоих объектов. И вы также видите те же данные для Customer1 в окне консоли.