Nhibernate-queryover-queries

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

NHibernate-QueryOverクエリ

この章では、QueryOverクエリについて説明します。 次のクエリに示すように、メソッドチェーン構文を使用したLINQに似た新しい構文です。

var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "Laverne");
  • それはまだ隠れた基準ですが、今ではクエリは強く型付けされています。
  • 基準クエリで見たように、最初の名前は単なる不透明な文字列であり、実際には x.FirstName を使用しているため、最初の名前はリファクタリングされ、名前が変更されます。クエリオーバー。
  • 似たようなことはまだたくさんできますが、クエリの理解構文をクエリオーバーで使用することはできません。メソッドチェーン構文を使用する必要があり、リンクと条件を組み合わせて一致させることはできません。
  • 多くのクエリでは、APIを介したクエリは非常に便利で、Criteriaを直接使用するよりもオブジェクトの構文を理解するのがはるかに簡単です。

クエリオーバーを使用して、名前がLaverneである顧客を取得する簡単な例を見てみましょう。

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 customers = session.QueryOver<Customer>()
               .Where(x => x.FirstName == "Laverne");

            foreach (var customer in customers.List()) {
               Console.WriteLine(customer);
            }

            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;
      }
   }
}

お分かりのように、それはまだカバーの下の基準ですが、より良い構文です。

上記のコードをコンパイルして実行すると、次の出力が表示されます。

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

Press <ENTER> to exit...

欠点の1つは、次のプログラムに示すように、* FirstName.StartsWith(“ A”)*と言いたいことです。

var customers = session.QueryOver<Customer>() .Where(x => x.FirstName.StartsWith("A"));

foreach (var customer in customers.List()) {
   Console.WriteLine(customer);
}

tx.Commit();

アプリケーションを再度実行してみましょう。この StartsWith メソッドがわからないため、これはLINQプロバイダーではないことがわかります。したがって、* RunTime例外*が発生します。

実行時例外

例外は、認識されないメソッド呼び出しを示しています。 ここでは明らかなことを行っていますが、必ずしも機能するとは限りません。

次のコードに示すように、FirstNameが「A%」に等しいなど、他のことを試してみましょう。

var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "A%");

foreach (var customer in customers.List()) {
   Console.WriteLine(customer);
}

もう一度実行してみましょう。次のように結果が返されないことがわかります。

Press <ENTER> to exit...

結果が得られない理由を理解するために、NHibernateプロファイラーを見てみましょう。

NHibernateプロファイルの結果

ご覧のとおり、名はA%に等しく、そうではありません。 A%は、like演算子を使用したSQLで使用されます。 次のプログラムに示すように、WHERE句に制限を作成する必要があります。

var customers = session.QueryOver<Customer>()
   .Where(Restrictions.On<Customer>(c => c.FirstName).IsLike("A%"));

foreach (var customer in customers.List()) {
   Console.WriteLine(customer);
}

アプリケーションを再度実行してみましょう。すべての顧客が、Aで始まる名で取得されていることがわかります。

Alejandrin Will (4ea3aef6-6bce-11e1-b0b4-6cf049ee52be)
   Points: 24
   HasGoldStatus: False
   MemberSince: 10/1/2011 12:00:00 AM (Utc)
   CreditRating: VeryVeryGood
   AverageRating: 0

   Orders:
      Order Id: 4ea3aef6-6bce-11e1-b0b5-6cf049ee52be

Austyn Nolan (4ea871b6-6bce-11e1-b110-6cf049ee52be)
   Points: 67
   HasGoldStatus: True
   MemberSince: 12/29/2007 12:00:00 AM (Utc)
   CreditRating: Neutral
   AverageRating: 0

   Orders:
      Order Id: 4ea871b6-6bce-11e1-b111-6cf049ee52be

Antonia Murphy (4ea871b6-6bce-11e1-b121-6cf049ee52be)
   Points: 72
   HasGoldStatus: True
   MemberSince: 6/15/2009 12:00:00 AM (Utc)
   CreditRating: Terrible
   AverageRating: 0

   Orders:
      Order Id: 4ea871b6-6bce-11e1-b122-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b123-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b124-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b125-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b126-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b127-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b128-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b129-6cf049ee52be
      Order Id: 4ea871b6-6bce-11e1-b12a-6cf049ee52be

この新しい QueryOver 構文を使用することを除いて、以前と同じように機能します。 多くの開発者は、LINQ構文がより親しみやすく、多くの場合正しいことを行うことを認識しています。

LINQで処理できない場合は、HQLまたは基準を調べて、それがより適切かどうかを確認します。

異なる構文を提供するだけなので、作成基準とQueryOverの両方の基準は、NHibernateを使用してデータベースからデータを引き出すことができるさらに別のクエリメカニズムを提供します。