📅  最后修改于: 2020-11-19 05:41:17             🧑  作者: Mango
在本章中,我们将介绍“加载”和“获取”功能的工作方式以及如何使用它们。这是ISession提供的两个非常相似的API,用于通过主键加载对象。
Get-将返回对象或null。
加载-它会返回对象,或者抛出ObjectNotFoundException 。
现在,为什么我们要使用这两个不同的API?
这是因为Load可以更有效地优化数据库往返。
实际上,Load会返回一个代理对象,并且在发出该Load调用时不需要直接访问数据库。
当您访问该代理时,该对象恰巧不在数据库中,此时它可能会抛出ObjectNotFoundException。
相反,由于CLR或公共语言运行时的限制,使用Get时,NHibernate必须立即进入数据库,检查对象是否在那里,如果不存在则返回null。
它没有对象选项来延迟获取操作,将往返数据库的操作推迟到以后的时间,因为它无法返回代理对象,并且在用户实际访问它时会将该代理对象交换为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 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 to exit...
如您所见,已打印出Customer1数据,但Customer2数据为空,这是因为Customer2记录在数据库中不可用。
当您再次运行您的应用程序时,我们可以在commit语句之前插入一个断点,然后让我们在“监视”窗口中查看两个客户。
如您所见,Customer1数据可用,而Customer2为空,并且两者的类型均为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;
}
}
}
现在让我们运行此示例,您将看到抛出了以下异常,如屏幕截图所示。
现在,如果您查看“监视”窗口,您将看到类型是两个对象的客户代理。并且您还会在控制台窗口上看到与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