Implémenter la persistance de données avec le framework ORM Fluent NHibernate

Temps approximatif : 1 heure et 8 minutes

NHibernate est un ORM open source, un framework de mapping objet-relationnel qui sert à mapper les classes objets C# du model avec les tables d'une base de données relationnelle

Le mapping objet dans NHibernate se fait à l'aide de fichiers xml mais ici nous allons faire le mapping avec Fluent NHibernate

Cher développeur csharp, Vous êtes Prêts ?

1 - Créer une Application Windows Form



2 - Créer une interface simple avec les objets suivants
  • txtId, txtNom, txtPrenom, txtAge
  • btnCharger, btnInserer, btnModifier
  • dgView


3 - Créer une base de données DB_TEST et une table PRS_PERSONNE









4 - Ajouter les répertoires suivants

Ajouter les 3 répertoires suivants dans l'arborescence du projet :
  • Forms
  • Mappings
  • Model


5 - Déplacer Form1 dans le répertoire Forms

Renommer Form1 en frmFraterie et Déplacer-la dans le répertoire Forms

6 - Installer et référencer NHibernate

Installer le deux packages suivants avec Nuget Package Manager :

(clique droit sur référence/gérer les packages nuget)


- NHibernate 4.1.1.4000 (par NHibernate Comunity) 4 millions de téléchargements


- FluentNHibernate (par James Gregory) version 2.0.2


7 - Ajouter la classe de définition Personne.cs dans Model

namespace Fraterie.Model
{
    public class Personne
    {
        public virtual int Id { get; set; }
        public virtual string Nom { get; set; }
        public virtual string Prenom { get; set; }
        public virtual int Age { get; set; }
    }
}
 

8 - Réaliser le mapping des entités

Ici nous avons une seule entité et elle s'appelle : Personne

Ajouter la classe de mapping PersonneMapping.cs dans le répertoire Mappings

using FluentNHibernate.Mapping;
namespace Fraterie.Mappings
{
    public class PersonneMapping:ClassMap<Model.Personne>
    {
        public PersonneMapping()
        {
            Id( x => x.Id );
            Map( x => x.Nom ).Not.Nullable();
            Map( x => x.Prenom ).Not.Nullable();
            Map( x => x.Age ).Not.Nullable();
            Table("PRS_PERSONNE");
        }
    }
}
 

9 - Ajouter à la racine du projet une classe SessionFactory.cs

using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
namespace Fraterie
{
    public class SessionFactory
    {
        private static volatile ISessionFactory iSessionFactory;
        private static object syncRoot = new object();

        public static ISession OpenSession
        {
            get
            {
                if (iSessionFactory == null)
                {
                    lock (syncRoot)
                    {
                        if (iSessionFactory == null)
                        {
                            iSessionFactory = BuildSessionFactory();
                        }
                    }
                }
                return iSessionFactory.OpenSession();
            }
        }
    }
}
 

10 - Changer la portée de la classe Program.cs

Nous allons dans Program.cs pour changer la déclaration de la classe de static vers public

    public class Program
 

11 - Ajouter system.configuration

Nous allons faire un clique droit sur références pour ajouter system.configuration


12 - Créer BuildSessionFactory()

Nous allons ajouter la fonction BuildSessionFactory() dans SessionFactory

    private static ISessionFactory BuildSessionFactory()
    {
        try
        {
            string connection_string = System.Configuration.ConfigurationManager.AppSettings["connection_string"];
            return Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2012.ConnectionString(connection_string))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>())
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();
        }catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message);
            throw ex;
        }
    }
 

13 - Créer BuildSchema() et CreateMappings() :

Nous allons ajouter les fonctions BuildSchema() et CreateMappings() dans SessionFactory

        private static void BuildSchema(NHibernate.Cfg.Configuration config)
        {
        }

        private static AutoPersistenceModel CreateMappings()
        {
            return AutoMap
                .Assembly(System.Reflection.Assembly.GetCallingAssembly())
                .Where(testc => testc.Namespace == "Fraterie.Model");
        }
 

14 - Spécifier le serveur SQL

Nous allons ajouter la chaîne de connexion sql dans app.config

    </startup>
  <appSettings>
    <add key="connection_string" value="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DB_TEST;" />
  </appSettings>
 

15 - Coder l'interface utilisateur

Nous allons dans frmFraterie pour ajouter le code de chargement de données

using NHibernate;
        private void frmFraterie_Load(object sender, EventArgs e)
        {
            chargerFraterieData();
        }

        private void btnCharger_Click(object sender, EventArgs e)
        {
            chargerFraterieData();
        }
        private void chargerFraterieData()
        {
            ISession session = SessionFactory.OpenSession;
            using (session)
            {
                IQuery query = session.CreateQuery("FROM Personne");
                IList<Model.Personne> personneInfo = query.List<Model.Personne>();
                dgView.DataSource = personneInfo;
            }
        }
 
Si vous avez le message d'erreur suivant

toto_truc is not mapped

Alors vous avez fais l'erreur de mettre le nom de votre table dans la requête HQL de Nhibernate

session.CreateQuery("FROM Toto_Truc");

corrigez ça en mettant le nom de la classe que vous avez mappée au lieu du nom de la table :

session.CreateQuery("FROM Personne");

N'oubliez pas, lorsque vous utilisez des requêtes HQL vous interroger le model pas la base

Si vous avez le message d'erreur suivant

could not execute query
Invalid column name 'TotoTruc'


Là vous avez utilisé dans votre classe de mapping des champs qui n'existent pas dans votre table !
Nous avons terminé l'essentiel, nous pouvons entrer manuellement des données dans la base et les charger dans le data grid à l'aide du bouton

16 - Nous allons implémenter l'insertion

        private void btnInserer_Click(object sender, EventArgs e)
        {
            Model.Personne personneData = new Model.Personne();
            definirPersonneData(personneData);
            ISession session = SessionFactory.OpenSession;
            using (session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.Save(personneData);
                        transaction.Commit();
                        chargerFraterieData();

                        txtNom.Text = "";
                        txtPrenom.Text = "";
                        txtAge.Text = "";
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        System.Windows.Forms.MessageBox.Show(ex.Message);
                        throw ex;
                    }
                }
            }
        }
        private void definirPersonneData(Model.Personne personne)
        {
            personne.Nom = txtNom.Text;
            personne.Prenom = txtPrenom.Text;
            personne.Age = int.Parse(txtAge.Text);
        }
 

17 - Nous allons implémenter la mise à jour

        private void btnModifier_Click(object sender, EventArgs e)
        {
            ISession session = SessionFactory.OpenSession;
            using (session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        IQuery query = session.CreateQuery("FROM Personne WHERE id = '" + txtId.Text + "'");
                        Model.Personne personneData = query.List<Model.Personne>()[0];
                        definirPersonneData(personneData);
                        session.Update(personneData);
                        transaction.Commit();
                        chargerFraterieData();
                        txtId.Text = "";
                        txtNom.Text = "";
                        txtPrenom.Text = "";
                        txtAge.Text = "";
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        System.Windows.Forms.MessageBox.Show(ex.Message);
                        throw ex;
                    }
                }
            }
        }
 

Pour faire la mise à jour nous avons besoin de charger les données par un clique dans le data grid pour récupérer l'id de l'élément à mettre à jour :

        private void dgView_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgView.RowCount <= 1 || e.RowIndex < 0)
                return;
            string id = dgView[0, e.RowIndex].Value.ToString();

            if (id == "")
                return;
            IList<Model.Personne> personneInfo = getDataFromFraterie(id);
            txtId.Text = personneInfo[0].Id.ToString();
            txtNom.Text = personneInfo[0].Nom.ToString();
            txtPrenom.Text = personneInfo[0].Prenom.ToString();
            txtAge.Text = personneInfo[0].Age.ToString();
        }
        private IList<Model.Personne> getDataFromFraterie(string id)
        {
            ISession session = SessionFactory.OpenSession;
            using (session)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        IQuery query = session.CreateQuery("From Personne where id = '" + id + "'");
                        return query.List<Model.Personne>();
                    }
                    catch (Exception ex)
                    {
                        System.Windows.Forms.MessageBox.Show(ex.Message);
                        throw ex;
                    }
                }
            }
        }
 



Voilà cher développeur C# vous savez maintenant implémenter la persistance de données avec Fluent NHibernate !

Regardez cette vidéo pour vous remémorer ces étapes ou Télécharger le code source
Attention : Vous devez restaurer les packages NuGet (Ouvrez NuGet Package Manager et cliquez sur Restaurer)
Commentaires
SnowNow a dit :
Je cherchait un article sur ce sujet. Encore une fois merci !

mardi 16 avril 2019.



Laisser un commentaire
E-mail (obligatoire) (strictement confidentielle)

Nom (obligatoire)

Site web

Entrez votre commentaire...

Question de sécurité : Combien font 1 + 1 ?



























Développé par Developpeur-Csharp.com
Mentions légales
Testé et compatible, à partir de : Firefox 3, Internet Explorer 7.0, Safari 4, Chrome, et Opera 9.
















Newsletter
Abonnez-vous à ma newsletter pour ne rater aucun article !
Adresse mail :

Discussion
Instantanée