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...

단점 중 하나는 다음과 같이 말하고 싶다는 것입니다. 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 %와 같지 않습니다. 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 또는 Criteria를 살펴보고 더 적합한 지 확인합니다.

단지 다른 구문을 제공하므로 Criteria, create criteria 및 QueryOver는 NHibernate를 사용하여 데이터베이스에서 데이터를 가져올 수있는 또 다른 쿼리 메커니즘을 제공합니다.