Nhibernate-load-get

提供:Dev Guides
移動先:案内検索

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の違いを見る簡単な例を見てみましょう。 同じドメインクラス CustomersOrders 、および同様に前の章の同じマッピングファイルを使用します。

この例では、最初に次のプログラムに示すように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レコードがデータベースで使用できないためです。

アプリケーションを再度実行するとき、コミットステートメントの前にブレークポイントを挿入し、[ウォッチ]ウィンドウで両方の顧客を見てみましょう。

Customer2 Record

ご覧のとおり、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;
      }
   }
}

この例を実行してみましょう。スクリーンショットに示されているように、次の例外がスローされます。

例外Nhibernateプロファイル

[ウォッチ]ウィンドウを見ると、タイプが両方のオブジェクトのカスタマープロキシであることがわかります。 また、コンソールウィンドウに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