NHibernate - Requêtes QueryOver

Dans ce chapitre, nous couvrirons les requêtes QueryOver. Il s'agit d'une nouvelle syntaxe qui ressemble plus à LINQ en utilisant la syntaxe de la chaîne de méthodes comme indiqué dans la requête suivante.

var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "Laverne");
  • C'est encore des critères sous les couvertures, mais maintenant nos requêtes sont fortement typées.

  • Comme nous l'avons vu dans la requête de critères, le prénom est juste une chaîne opaque, maintenant nous utilisons en fait un x.FirstName, de sorte que le prénom est remanié et renommé qui est modifié dans la requête de critères de style de lien à l'aide de la requête over.

  • Nous pouvons encore faire beaucoup de choses similaires, mais vous ne pouvez pas utiliser la syntaxe de compréhension de requête avec query over, vous devez utiliser la syntaxe de la chaîne de méthodes et vous ne pouvez pas mélanger et faire correspondre le lien et les critères.

  • Pour de nombreuses requêtes, la requête via l'API est très utile et fournit une syntaxe d'objet beaucoup plus facile à comprendre que l'utilisation directe de critères.

Jetons un coup d'œil à un exemple simple dans lequel nous récupérerons un client dont le prénom est Laverne à l'aide d'une requête over.

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

Comme vous pouvez le voir, il s'agit toujours de critères sous les couvertures, mais c'est juste une syntaxe plus agréable.

Lorsque le code ci-dessus est compilé et exécuté, vous verrez la sortie suivante.

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

L'un des inconvénients est que, disons que nous voulons dire que FirstName.StartsWith(“A”) comme indiqué dans le programme suivant.

var customers = session.QueryOver<Customer>() .Where(x => x.FirstName.StartsWith("A"));
 
foreach (var customer in customers.List()) { 
   Console.WriteLine(customer); 
} 

tx.Commit();

Maintenant, exécutons à nouveau l'application et vous verrez que ce n'est pas un fournisseur LINQ car il ne sait pas ce que cela StartsWith méthode est, donc vous obtiendrez un RunTime exception.

L'exception indique un appel de méthode non reconnu. Ici, nous faisons la chose évidente, mais cela ne fonctionne pas nécessairement.

Essayons autre chose, comme FirstName est égal à «A%» comme indiqué dans le code suivant.

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

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

Exécutons à nouveau ceci et vous verrez que nous n'obtiendrons aucun résultat comme indiqué ci-dessous.

Press <ENTER> to exit...

Pour comprendre pourquoi nous n'obtenons aucun résultat, jetons un œil au profileur NHibernate.

Comme vous pouvez le voir, le prénom est égal à A% qui ne l'est pas. Un% est utilisé en SQL avec l'opérateur like. Nous devons maintenant créer une restriction dans la clause WHERE comme indiqué dans le programme suivant.

var customers = session.QueryOver<Customer>() 
   .Where(Restrictions.On<Customer>(c => c.FirstName).IsLike("A%")); 
	
foreach (var customer in customers.List()) { 
   Console.WriteLine(customer); 
}

Exécutons à nouveau votre application et vous verrez que tous les clients sont récupérés avec le prénom commençant par 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

Cela fonctionne de la même manière qu'avant, sauf en utilisant ce nouveau QueryOversyntaxe. De nombreux développeurs trouvent que la syntaxe LINQ est plus accessible et fait souvent les bonnes choses.

Si LINQ ne peut pas le gérer, alors vous commencerez à regarder HQL ou Criteria pour voir si cela sera plus approprié.

Il vous donne juste une syntaxe différente, donc Criteria, les critères de création et QueryOver vous fournissent juste un autre mécanisme d'interrogation qui vous permet d'extraire des données de la base de données en utilisant NHibernate.