开发手册 欢迎您!
软件开发者资料库

NHibernate - 加载/获取

NHibernate加载/获取 - 从概述,架构,Orm,环境设置,入门,基本Orm,基本Crud操作,Profiler,添加Intelliesnse到映射文件,数据类型映射,配置,覆盖配置,批量大小,缓存,学习NHibernate映射组件,关系,集合映射,级联,延迟加载,反向关系,加载/获取,Linq,Hibernate查询语言,条件查询,QueryOver查询,本机Sql,流利Hibernate。

在本章中,我们将介绍Load和Get功能的工作方式以及我们如何使用它们.这是由 ISession 提供的两个非常相似的API,用于通过主键加载对象.

  • 获取 : 它将返回对象或null.

  • 加载 : 它将返回对象,否则将抛出 ObjectNotFoundException .

现在,为什么我们有这两个不同的API?

加载

  • 这是因为Load可以优化数据库往返次数更有效率.

  • 加载实际返回一个代理对象,并且在发出加载调用时无需立即访问数据库.

  • 当您访问该代理时,该对象不会出现在数据库中,它可能会在此时抛出ObjectNotFoundException.

获取

  • 相反,由于CLR的限制或使用Get 公共语言运行时和NHibernate必须立即进入数据库,检查对象是否存在并返回null,如果它不存在.

  • 它没有延迟fetch的对象选项,因为往返于数据库的数据库当用户实际访问它时,它无法返回代理对象并将该代理对象换成null.

让我们有一个看一个简单的例子,你将看到它们是如何实际使用的,以及Get和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.Get(id1);             Console.WriteLine("Customer1 data");             Console.WriteLine(customer1);            var customer2 = session.Get(id2);             Console.WriteLine("Customer2 data");             Console.WriteLine(customer2);             tx.Commit();          }         Console.WriteLine("Press  to exit...");          Console.ReadLine();       }      private static Configuration ConfigureNHibernate() {         NHibernateProfiler.Initialize();          var cfg = new Configuration();                   cfg.DataBaseIntegration(x => {             x.ConnectionStringName = "default";             x.Driver();             x.Dialect();             x.IsolationLevel = IsolationLevel.RepeatableRead;            x.Timeout = 10;             x.BatchSize = 10;          });                   cfg.SessionFactory().GenerateStatistics();         cfg.AddAssembly(Assembly.GetExecutingAssembly());          return cfg;       }    }}

您可以看到我们有两个 Guid ID ,第一个是一个好的ID,它是我们知道在数据库中的客户的ID.虽然数据库中不存在第二个ID.这两个ID都作为参数传递给 Get()方法,然后结果打印在控制台上.

当编译并执行上面的代码时将看到以下输出.

Customer1 dataLaverne Hegmann (4e97c816-6bce-11e1-b095-6cf049ee52be)   Points: 74   HasGoldStatus: True   MemberSince: 4/4/2009 12:00:00 AM (Utc)   CreditRating: Neutral   AverageRating: 0Orders:   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-6cf049ee52beCustomer2 dataPress  to exit...

正如您所看到的那样打印了Customer1数据但Customer2数据为空,这是因为Customer2记录在数据库.

再次运行应用程序时,我们可以在commit语句之前插入一个断点,然后让我们在Watch窗口中查看两个客户.

Customer2 Record

您可以看到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(id1);             Console.WriteLine("Customer1 data");             Console.WriteLine(customer1);            var customer2 = session.Load(id2);             Console.WriteLine("Customer2 data");             Console.WriteLine(customer2);             tx.Commit();          }         Console.WriteLine("Press  to exit...");          Console.ReadLine();       }      private static Configuration ConfigureNHibernate() {          NHibernateProfiler.Initialize();          var cfg = new Configuration();                   cfg.DataBaseIntegration(x => {             x.ConnectionStringName = "default";             x.Driver();             x.Dialect();             x.IsolationLevel = IsolationLevel.RepeatableRead;             x.Timeout = 10;            x.BatchSize = 10;          });          cfg.SessionFactory().GenerateStatistics();         cfg.AddAssembly(Assembly.GetExecutingAssembly());          return cfg;       }    } }

现在让我们运行这个例子,您将看到抛出以下异常在屏幕截图中.

Exception Nhibernate Profile

现在,如果你看看在Watch窗口中,您将看到类型是两个对象的客户代理.您还可以在控制台窗口中看到Customer1的相同数据.

Customer1 dataLaverne 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