Nhibernate-load-get
NHibernate-ロード/取得
この章では、LoadおよびGet機能がどのように機能し、どのように使用できるかについて説明します。 これらは、主キーによってオブジェクトをロードするために ISession によって提供される2つの非常に類似したAPIです。
- Get -オブジェクトまたはnullを返します。
- Load -オブジェクトを返すか、 ObjectNotFoundException をスローします。
さて、なぜこれら2つの異なるAPIがあるのでしょうか?
Load
- これは、Loadがデータベースのラウンドトリップをより効率的に最適化できるためです。
- Loadは実際にプロキシオブジェクトを返すため、Load呼び出しを発行するときにデータベースにアクセスする必要はありません。
- そのプロキシにアクセスすると、オブジェクトはデータベースに存在しないため、その時点でObjectNotFoundExceptionをスローする可能性があります。
Get
- 逆に、CLRまたは Common Language Runtime の制限のためにGetを使用し、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;
}
}
}
ご覧のとおり、2つの Guid IDがあります。最初のIDは適切なIDです。データベースにあることがわかっているのは顧客のIDです。 一方、2番目の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 です。
次のコードに示すのと同じ例で、Getの代わりにLoadメソッドを使用してみましょう。
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