NHibernate - Mappage des types de données

Dans ce chapitre, nous couvrirons les types de données cartographiques. Le mappage des entités est simple, les classes d'entités sont toujours mappées aux tables de base de données en utilisant<class>, <subclass>, and <joined-subclass>éléments de cartographie. Les types de valeur ont besoin de quelque chose de plus, c'est là que les types de mappage sont requis.

NHibernate est capable de cartographier une grande variété de types de données. Voici la liste des types de données les plus courants pris en charge.

Type de mappage Type .NET System.Data.DbType
Int16 System.Int16 DbType.Int16
Int32 System.Int32 DbType.Int32
Int64 System.Int64 DbType.Int64
Célibataire Système unique DbType.Single
Double Système.Double DbType.Double
Décimal System.Decimal DbType.Decimal
Chaîne System.String DbType.String
AnsiString System.String DbType.AnsiString
Octet System.Byte DbType.Byte
Carboniser System.Char DbType.StringFixedLength: un caractère
AnsiChar System.Char DbType.AnsiStringFixedLength: un caractère
Booléen System.Boolean DbType.Boolean
Guid Système.Guid DbType.Guid
PersistentEnum System.Enum (une énumération) DbType pour la valeur sous-jacente
Vrai faux System.Boolean DbType.AnsiStringFixedLength: «T» ou «F»
Oui Non System.Boolean DbType.AnsiStringFixedLength: «Y» ou «N»
DateHeure DateHeure DbType.DateTime: ignore les millisecondes
Les tiques System.DateTime DbType.Int64
TimeSpan System.TimeSpan DbType.Int64
Horodatage System.DateTime DbType.DateTime - aussi spécifique que la base de données le prend en charge
Binaire System.Byte [] DbType.Binary
BinaryBlob System.Byte [] DbType.Binary
StringClob System.String DbType.String
Sérialisable Tout objet System.Object marqué avec SerializableAttribute DbType.Binary
CultureInfo System.Globalization.CultureInfo DbType.String: cinq caractères pour la culture
Type Type de système DbType.String contenant le nom qualifié d'assembly

Le tableau ci-dessus explique en détail les pointeurs mentionnés ci-dessous.

  • Tout, des types numériques simples aux chaînes, qui peuvent être mappées de différentes manières en utilisant varchars, chars etc. ainsi que des blobs de chaînes et toute la variété de types pris en charge par les bases de données.

  • Il est également capable de cartographier Booleans, à la fois vers des champs utilisant des zéros et des uns, des champs de caractères contenant vrai, faux ou T et F.

  • Il existe une grande variété de façons de définir la façon dont cela correspond aux valeurs booléennes principales de la base de données.

  • Nous pouvons gérer la cartographie de DateTime, incluant et excluant les décalages de fuseau horaire, l'heure d'été, etc.

  • Nous pouvons également cartographier enumerations; nous pouvons les mapper à des chaînes ou à leurs valeurs numériques sous-jacentes.

Jetons un coup d'œil à un exemple simple dans lequel nous avons les mêmes noms de propriétés à la fois dans la base de données et dans la classe Student.

Modifions maintenant le FirstMidName en FirstName dans la classe étudiant, où nous ne changerons pas la colonne FirstMidName, mais nous verrons comment dire à NHibernate know d'effectuer cette conversion. Voici la classe étudiante mise à jour.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;

namespace NHibernateDemoApp { 
  
   class Student { 
      public virtual int ID { get; set; } 
      public virtual string LastName { get; set; } 
      public virtual string FirstName { get; set; } 
   }
}

Voici l'implémentation du fichier de mappage NHibernate.

<?xml version = "1.0" encoding = "utf-8" ?> 
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemoApp" 
   namespace = "NHibernateDemoApp"> 
   
   <class name = "Student">
	
      <id name = "ID"> 
         <generator class = "native"/>
      </id> 
   
      <property name = "LastName"/> 
      <property name = "FirstName" column = "FirstMidName" type = "String"/> 
   </class> 

</hibernate-mapping>

Dans cet exemple, supposons que le champ FirstName est une chaîne .NET et que la colonne FirstMidName est un SQL nvarchar. Maintenant, pour dire à NHibernate comment effectuer cette conversion, définissez le nom égal àFirstName et colonne égale à FirstMidName et spécifiez le type de mappage égal à String, qui est approprié pour cette conversion particulière.

Ce qui suit est un Program.cs implémentation de fichier.

using HibernatingRhinos.Profiler.Appender.NHibernate; 
using NHibernate.Cfg; 
using NHibernate.Dialect; 
using NHibernate.Driver; 

using System; 
using System.Linq; 
using System.Reflection;

namespace NHibernateDemoApp { 

   class Program { 
	
      static void Main(string[] args) { 
		
         NHibernateProfiler.Initialize(); 
         var cfg = new Configuration(); 
			
         String Data Source = asia13797\\sqlexpress;
         String Initial Catalog = NHibernateDemoDB;
         String Integrated Security = True;
         String Connect Timeout = 15;
         String Encrypt = False;
         String TrustServerCertificate = False;
         String ApplicationIntent = ReadWrite;
         String MultiSubnetFailover = False;
         
         cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + 
            Initial Catalog + Integrated Security + Connect Timeout + Encrypt +
            TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; 
            
            x.Driver<SqlClientDriver>(); 
            x.Dialect<MsSql2008Dialect>(); 
            x.LogSqlInConsole = true; 
         }); 
         
         cfg.AddAssembly(Assembly.GetExecutingAssembly()); 
         var sefact = cfg.BuildSessionFactory();
			
         using (var session = sefact.OpenSession()) { 
            
            using (var tx = session.BeginTransaction()) { 
               var students = session.CreateCriteria<Student>().List<Student>(); 
               Console.WriteLine("\nFetch the complete list again\n"); 
               
               foreach (var student in students) { 
                  Console.WriteLine("{0} \t{1} \t{2}", student.ID, student.FirstName,
                     student.LastName); 
               } 
					
               tx.Commit(); 
            } 
				
            Console.ReadLine(); 
         } 
      } 
   }
}

Maintenant, lorsque vous exécutez votre application, vous verrez la sortie suivante.

NHibernate: SELECT this_.ID as ID0_0_, this_.LastName as LastName0_0_, 
   this_.FirstMidName as FirstMid3_0_0_ FROM Student this_

Fetch the complete list again
3 Allan Bommer
4 Jerry Lewis

Comme vous pouvez le voir, il a mappé le nom de propriété différent au nom de la colonne dans la base de données.

Jetons un coup d'œil à un autre exemple dans lequel nous ajouterons une autre propriété dans la classe Student de enumtype. Voici l'implémentation de la classe Student.

using System; 
using System.Collections.Generic; 
using System.Linq; using System.Text; 
using System.Threading.Tasks; 

namespace NHibernateDemoApp { 
   
   class Student { 
      public virtual int ID { get; set; } 
      public virtual string LastName { get; set; } 
      public virtual string FirstName { get; set; } 
      public virtual StudentAcademicStanding AcademicStanding { get; set; } 
   } 
   
   public enum StudentAcademicStanding { 
      Excellent, 
      Good, 
      Fair, 
      Poor, 
      Terrible 
   } 
}

Comme vous pouvez le voir, l'énumération a une variété de valeurs différentes qu'elle peut éventuellement avoir, telles que Excellent, Bon, Passable, Pauvre et Terrible.

En passant au fichier de mappage, vous pouvez voir que chacune de ces propriétés est répertoriée dans le fichier de mappage, y compris le fichier nouvellement ajouté AcademicStanding propriété.

<?xml version = "1.0" encoding = "utf-8" ?> 
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" 
   assembly = "NHibernateDemoApp" namespace = "NHibernateDemoApp"> 
   
   <class name = "Student"> 
	
      <id name = "ID"> 
         <generator class = "native"/> 
      </id> 

      <property name = "LastName"/> 
      <property name = "FirstName" column = "FirstMidName" type = "String"/> 
      <property name = "AcademicStanding"/> 
   </class>  

</hibernate-mapping>

Maintenant, nous devons également changer la base de données, alors allez dans l'Explorateur d'objets SQL Server et cliquez avec le bouton droit sur la base de données et sélectionnez l'option Nouvelle requête….

Il ouvrira l'éditeur de requête, puis spécifiera la requête ci-dessous.

DROP TABLE [dbo].[Student]

CREATE TABLE [dbo].[Student] ( 
   [ID] INT IDENTITY (1, 1) NOT NULL, 
   [LastName] NVARCHAR (MAX) NULL, 
   [FirstMidName] NVARCHAR (MAX) NULL, 
   [AcademicStanding] NCHAR(10) NULL, 
   CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC) 
);

Cette requête supprimera d'abord la table Student existante, puis créera une nouvelle table.

Cliquez sur l'icône Exécuter comme indiqué ci-dessus. Une fois la requête exécutée avec succès, vous voyez un message.

Développez la base de données et la liste déroulante Table, puis cliquez avec le bouton droit sur la table Student et sélectionnez View Designer.

Maintenant, vous verrez la table nouvellement créée, qui a également la nouvelle propriété AcademicStanding.

Ajoutons deux enregistrements comme indiqué ci-dessous Program.cs fichier.

using HibernatingRhinos.Profiler.Appender.NHibernate; 
using NHibernate.Cfg; 
using NHibernate.Dialect; 
using NHibernate.Driver; 

using System; 
using System.Linq; 
using System.Reflection;

namespace NHibernateDemoApp { 

   class Program { 
      
      static void Main(string[] args) { 
		
         NHibernateProfiler.Initialize(); 
         var cfg = new Configuration(); 
			
         String Data Source = asia13797\\sqlexpress;
         String Initial Catalog = NHibernateDemoDB;
         String Integrated Security = True;
         String Connect Timeout = 15;
         String Encrypt = False;
         String TrustServerCertificate = False;
         String ApplicationIntent = ReadWrite;
         String MultiSubnetFailover = False;
         
         cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + 
            Initial Catalog + Integrated Security + Connect Timeout + Encrypt +
            TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; 
            
            x.Driver<SqlClientDriver>(); 
            x.Dialect<MsSql2008Dialect>(); 
         }); 
         
         cfg.AddAssembly(Assembly.GetExecutingAssembly()); 
         var sefact = cfg.BuildSessionFactory(); 
         
         using (var session = sefact.OpenSession()) { 
            using (var tx = session.BeginTransaction()) { 
               
               var student1 = new Student { 
                  ID = 1, 
                  FirstName = "Allan", 
                  LastName = "Bommer",
                  AcademicStanding = StudentAcademicStanding.Excellent 
               };
               
               var student2 = new Student { 
                  ID = 2, 
                  FirstName = "Jerry", 
                  LastName = "Lewis", 
                  AcademicStanding = StudentAcademicStanding.Good 
               };
					
               session.Save(student1); 
               session.Save(student2);
               var students = session.CreateCriteria<Student>().List<Student>(); 
               Console.WriteLine("\nFetch the complete list again\n");
               
               foreach (var student in students) { 
                  Console.WriteLine("{0} \t{1} \t{2} \t{3}", student.ID,
                     student.FirstName, student.LastName, student.AcademicStanding); 
               } 
					
               tx.Commit(); 
            }
				
            Console.ReadLine(); 
         } 
      } 
   } 
}

Maintenant, exécutons votre application et vous verrez la sortie suivante sur la fenêtre de votre console.

Fetch the complete list again

1 Allan Bommer Excellent
2 Jerry Lewis Good

Examinons maintenant la base de données en faisant un clic droit sur la table des étudiants.

Sélectionnez Afficher les données et vous verrez les deux enregistrements dans la table des élèves, comme illustré dans la capture d'écran suivante.

Vous pouvez voir que deux enregistrements sont ajoutés et Allan a AcademicStanding 0 et Jerry a AcademicStanding 1. C'est parce que dans .Net la première valeur d'énumération par défaut a 0, ce qui est Excellent si vous regardez StudentAcademicStanding. Alors que dans le fichier Student.cs Good est le deuxième, il a donc une valeur de 1.