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();

ここでアプリケーションを再度実行してみましょう。これが何であるかがわからないため、これはLINQプロバイダーではないことがわかります。 StartsWith メソッドは、だからあなたは得るでしょう RunTime exception

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

次のコードに示すように、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プロファイラーを見てみましょう。

ご覧のとおり、名はA%と同じですが、そうではありません。%は、SQLでlike演算子を使用して使用されます。次に、次のプログラムに示すように、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またはCriteriaを調べて、それがより適切かどうかを確認します。

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