- 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