
- NHibernate 教程
- NHibernate - 首页
- NHibernate - 概述
- NHibernate - 架构
- NHibernate - ORM
- NHibernate - 环境设置
- NHibernate - 快速入门
- NHibernate - 基本ORM
- NHibernate - 基本CRUD操作
- NHibernate - 性能分析器
- 为映射文件添加IntelliSense
- NHibernate - 数据类型映射
- NHibernate - 配置
- NHibernate - 重写配置
- NHibernate - 批量大小
- NHibernate - 缓存
- NHibernate - 组件映射
- NHibernate - 关系
- NHibernate - 集合映射
- NHibernate - 级联操作
- NHibernate - 延迟加载
- NHibernate - 反向关系
- NHibernate - 加载/获取
- NHibernate - LINQ
- NHibernate - 查询语言 (HQL)
- NHibernate - Criteria 查询
- NHibernate - QueryOver 查询
- NHibernate - 原生SQL
- NHibernate - Fluent NHibernate
- NHibernate 有用资源
- NHibernate - 快速指南
- NHibernate - 有用资源
- NHibernate - 讨论
NHibernate - 加载/获取
本章将介绍Load和Get功能的工作方式以及如何使用它们。它们是ISession提供的两个非常相似的API,用于通过主键加载对象。
Get − 它将返回对象或null。
Load − 它将返回对象或抛出ObjectNotFoundException异常。
那么,为什么我们要使用这两个不同的API呢?
Load
这是因为Load可以更有效地优化数据库往返次数。
Load实际上返回一个代理对象,不需要在发出Load调用时立即访问数据库。
当您访问该代理对象时,如果该对象恰好不在数据库中,它会在那时抛出ObjectNotFoundException异常。
Get
相反,由于CLR(公共语言运行时)的限制,NHibernate必须立即访问数据库,检查对象是否存在,如果不存在则返回null。
它没有延迟数据库往返操作到以后的选项,因为它不能返回代理对象,并且当用户实际访问它时,不能将代理对象替换为null。
让我们来看一个简单的例子,您将看到这些方法的实际用法以及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 ID,第一个是有效的ID,它是我们知道存在于数据库中的客户的ID。而第二个ID不存在于数据库中。这两个ID都作为参数传递给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记录。
再次运行应用程序时,我们可以在commit语句之前设置断点,然后在监视窗口中查看这两个客户。

您可以看到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; } } }
现在让我们运行这个例子,您将看到抛出以下异常,如屏幕截图所示。

现在,如果您查看监视窗口,您将看到两个对象的类型都是customer代理。您还将在控制台窗口中看到Customer1的相同数据。
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