Comment mapper NHibernate du tableau A au tableau A lui-même avec plusieurs-à-plusieurs?

StackOverflow https://stackoverflow.com/questions/401207

  •  03-07-2019
  •  | 
  •  

Question

S'il vous plaît aider! Je n'arrivais pas à comprendre comment cartographier la situation suivante:

Je n'ai qu'une seule table.

  

[Table] Utilisateur {id, nom}

Ma classe ressemble à ceci

public class User
{
  public int Id { get; set; }
  public string Name { get; set; }

  public ISet<User> Friends { get; set; }
}

Chaque utilisateur a une relation avec d'autres utilisateurs. Par exemple, "L'utilisateur A" peut avoir beaucoup d'amis, ce qui est un autre utilisateur.

Quelle devrait être la cartographie pour cela? Je pense que cela devrait être une relation plusieurs à plusieurs, mais je ne sais pas vraiment à quoi ressemblera le HBM.

Merci,

Était-ce utile?

La solution

  

Je pense que cela devrait être plusieurs-à-plusieurs   relation

Vous avez raison. Dans votre scénario, vous devrez utiliser un mappage plusieurs à plusieurs auto-référentiel. Mais en utilisant une seule table Utilisateurs , vous ne pouvez pas représenter la relation entre utilisateurs et amis (en utilisant une seule table, vous pourriez représenter un référentiel auto-référentiel relation parent-enfant ). Vous aurez besoin d'une table intermédiaire pour y parvenir. Voici un exemple d'utilisation de SQLite ADO.NET fournisseur pour montrer un moyen possible de modéliser votre scénario:

User.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    namespace="Test" assembly="test">

    <class name="User" table="Users">
        <id name="Id" column="id">
            <generator class="native"/>
        </id>
        <property name="Name" column="name"/>
        <set name="Friends" table="Friends">
            <key column="user_id"/>
            <many-to-many class="User" column="friend_id"/>
        </set>
    </class>

</hibernate-mapping>

Dans le mappage ci-dessus, vous remarquerez l'utilisation des tableaux suivants: Utilisateurs et amis

Et voici le code:

using System;
using System.IO;
using System.Collections.Generic;
using System.Data.SQLite;
using NHibernate;
using NHibernate.Cfg;
using Iesi.Collections.Generic;

namespace Test
{
    class Program
    {
        public static void Main() 
        {
            if (File.Exists("nhibernate.db"))
            {
                File.Delete("nhibernate.db");
            }
            ExecuteCommand("create table Users (id integer, name string)");
            ExecuteCommand("create table Friends (user_id integer, friend_id string)");

            ExecuteCommand("insert into Users (id, name) values (1, 'user1')");
            ExecuteCommand("insert into Users (id, name) values (2, 'user2')");
            ExecuteCommand("insert into Users (id, name) values (3, 'user3')");

            // User1 is friend with User2    
            ExecuteCommand("insert into Friends (user_id, friend_id) values (1, 2)");
            // User1 is friend with User3    
            ExecuteCommand("insert into Friends (user_id, friend_id) values (1, 3)");
            // User2 is friend with User1    
            ExecuteCommand("insert into Friends (user_id, friend_id) values (2, 1)");
            // User3 is friend with User1    
            ExecuteCommand("insert into Friends (user_id, friend_id) values (3, 1)");

            ISessionFactory sessionFactory =
                new Configuration().Configure().BuildSessionFactory();
            ISession session = sessionFactory.OpenSession();
            User user = session.Get<User>(1);
            Console.WriteLine(user.Friends.Count);

            session.Close();
            sessionFactory.Close();
        }

        private static void ExecuteCommand(string sql)
        {
            using (SQLiteConnection connection = new SQLiteConnection("Data Source=nhibernate.db;Version=3"))
            using (SQLiteCommand command = new SQLiteCommand(sql, connection))
            {
                connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }

    class User 
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual ISet<User> Friends { get; set; }
    }
}

Et pour finir, voici mon fichier de configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section
            name="hibernate-configuration"
            type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"
        />
    </configSections>

    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
        <session-factory>
            <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
            <property name="connection.driver_class">NHibernate.Driver.SQLite20Driver</property>
            <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
            <property name="connection.connection_string">Data Source=nhibernate.db;Version=3</property>

            <mapping assembly="test" />
        </session-factory>
    </hibernate-configuration>
</configuration>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top