Comment mapper NHibernate du tableau A au tableau A lui-même avec plusieurs-à-plusieurs?
-
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,
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>