- NHibernate 教程
- NHibernate - 主页
- NHibernate - 概述
- NHibernate - 架构
- NHibernate-Orm
- NHibernate - 环境设置
- NHibernate - 入门
- NHibernate - 基本 Orm
- NHibernate - 基本 Crud 操作
- NHibernate - 分析器
- 将 Intelliesnse 添加到映射文件
- NHibernate - 数据类型映射
- NHibernate - 配置
- NHibernate - 覆盖配置
- NHibernate - 批量大小
- NHibernate - 缓存
- NHibernate - 映射组件
- NHibernate - 关系
- NHibernate - 集合映射
- NHibernate - 级联
- NHibernate - 延迟加载
- NHibernate - 逆关系
- NHibernate - 加载/获取
- NHibernate - Linq
- NHibernate - 查询语言
- NHibernate - 标准查询
- NHibernate - QueryOver 查询
- NHibernate - 原生 Sql
- NHibernate - 流畅的Hibernate
- NHibernate 有用资源
- NHibernate - 快速指南
- NHibernate - 有用的资源
- NHibernate - 讨论
NHibernate - 加载/获取
在本章中,我们将介绍“加载”和“获取”功能的工作原理以及如何使用它们。这是ISession提供的两个非常相似的 API,用于通过主键加载对象。
Get - 它将返回对象或 null。
Load - 它将返回对象,否则将抛出ObjectNotFoundException。
现在,为什么我们有这两个不同的 API?
加载
这是因为 Load 可以更有效地优化数据库往返。
Load 实际上返回一个代理对象,并且在您发出 Load 调用时不需要立即访问数据库。
当您访问该代理时,该对象恰好不在数据库中,此时它可能会抛出 ObjectNotFoundException。
得到
相反,由于 CLR 或公共语言运行时的限制,使用 Get时,NHibernate 必须立即访问数据库,检查对象是否存在,如果不存在则返回 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<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 记录在数据库中不可用。
当您再次运行应用程序时,我们可以在提交语句之前插入一个断点,然后让我们在“监视”窗口中查看这两个客户。
如您所见,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;
}
}
}
现在让我们运行这个示例,您将看到抛出以下异常,如屏幕截图所示。
现在,如果您查看“监视”窗口,您将看到这两个对象的类型都是客户代理。您还会在控制台窗口上看到 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