¿Cómo asignar NHibernate de la tabla A a la tabla A con many-to-many?
-
03-07-2019 - |
Pregunta
¡Por favor ayuda! No pude averiguar cómo mapear la siguiente situación:
Sólo tengo 1 tabla.
[Tabla] Usuario {id, nombre}
Mi clase se parece a esto
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public ISet<User> Friends { get; set; }
}
Cada usuario tiene relación con otros usuarios. por ejemplo, "Usuario A" puede tener muchos amigos, que es otro usuario.
¿Cuál debería ser el mapeo para esto? Creo que esta debería ser una relación de muchos a muchos, pero realmente no sé cómo se verá el HBM.
Gracias,
Solución
Creo que esto debería ser de muchos a muchos relación
Estás en lo correcto. En su escenario, necesitará utilizar una asignación de muchos a muchos autorreferencial. Pero al usar una sola tabla de Usuarios , no puede representar la relación entre usuarios y amigos (si usa una sola tabla, podría representar un autorreferencial relación padre-hijo ). Necesitará una tabla intermedia para lograr esto. Aquí hay un ejemplo usando SQLite ADO.NET proveedor para mostrar una posible forma de modelar su escenario:
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>
Desde la asignación anterior, notará el uso de las siguientes tablas: Usuarios y amigos
Y aquí está el código:
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; }
}
}
Y por último, para completar, aquí está mi archivo de configuración:
<?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>