NHibernate - Composant de cartographie
Dans ce chapitre, nous parlerons des composants de mappage. Dans NHibernate,component is a value object. Il n'a pas d'identité propre.
Un exemple de ceci serait un objet d'argent, un sac à main ou un portefeuille pourrait contenir de l'argent, mais l'identité exacte de cet argent n'a pas d'importance.
Il n'a pas sa propre clé primaire, mais les composants eux-mêmes sont persistants dans la même table que l'objet propriétaire.
Jetons un coup d'œil à un exemple simple dans lequel un étudiant a une adresse, qui est un objet de Location class associé avec.
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 virtual Location Address { get; set; }
}
public class Location {
public virtual string Street { get; set; }
public virtual string City { get; set; }
public virtual string Province { get; set; }
public virtual string Country { get; set; }
}
public enum StudentAcademicStanding {
Excellent,
Good,
Fair,
Poor,
Terrible
}
}
Maintenant, nous devons également mettre à jour la base de données en exécutant la requête suivante, qui supprimera d'abord la table Student, puis créera une nouvelle table qui contiendra également une colonne pour la classe Location.
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,
[Street] NVARCHAR (100) NULL,
[City] NVARCHAR (100) NULL,
[Province] NVARCHAR (100) NULL,
[Country] NVARCHAR (100) NULL,
CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC)
);
Maintenant, pour mapper les colonnes qui ne font pas directement partie de la classe Student, mais qui sont des propriétés de la classe Location et que l'objet de la classe Location est défini dans la classe Student. Nous avons besoin d'un composant pour le mapper correctement. Créons un composant dansstudent.hbm.xml fichier comme indiqué dans le code suivant.
<?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"/>
<component name = "Address">
<property name = "Street"/>
<property name = "City"/>
<property name = "Province"/>
<property name = "Country"/>
</component>
</class>
</hibernate-mapping>
Ce composant est l'Adresse et il possède ces différentes propriétés. Avec ces informations, NHibernate en a maintenant assez pour pouvoir cartographier cela.
Voici maintenant le fichier Program.cs dans lequel un nouvel objet étudiant est créé et initialisé, puis enregistré dans la base de données. Il récupérera ensuite la liste de la base de données.
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cache;
using NHibernate.Caches.SysCache;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;
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.Poor,
Address = new Location {
Street = "123 Street",
City = "Lahore",
Province = "Punjab",
Country = "Pakistan"
}
};
session.Save(student1);
tx.Commit();
var students = session.Query<Student>().ToList<Student>();
Console.WriteLine("\nFetch the complete list again\n");
foreach (var student in students) {
Console.WriteLine("{0} \t{1} \t{2} \t{3} \t{4} \t{5} \t{6} \t{7}",
student.ID,
student.FirstName,
student.LastName,
student.AcademicStanding,
student.Address.Street,
student.Address.City,
student.Address.Province,
student.Address.Country
);
}
}
Console.ReadLine();
}
}
}
}
Nous pouvons maintenant exécuter cette application et NHibernate peut enregistrer ces valeurs dans la base de données. Lorsque vous exécutez l'application, vous verrez la sortie suivante.
Fetch the complete list again
2 Allan Bommer Poor 123 Street Lahore Punjab Pakistan
Voici les valeurs de la base de données.
Les composants nous permettent de séparer les colonnes qui se trouvent dans une table de base de données dans leur propre classe distincte.
L'autre chose à noter ici est que l'emplacement est une classe, ce n'est pas une entité.
C'est un objet de type valeur et il n'a pas sa propre clé primaire.
Il est enregistré dans la même table que l'étudiant qui le contient.
C'est pourquoi nous utilisons le composant ici.
Cela permet une grande flexibilité pour changer notre couche de classe, la façon dont nos classes sont définies par rapport à la disposition de notre base de données.