Как сопоставить NHibernate из таблицы A с самой таблицей A с помощью "многие ко многим"?
-
03-07-2019 - |
Вопрос
Пожалуйста, помогите!Я не мог понять, как отобразить следующую ситуацию:
У меня есть только 1 таблица.
[Таблица] Пользователь { идентификатор, имя}
Мой класс выглядит вот так
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public ISet<User> Friends { get; set; }
}
Каждый пользователь имеет отношения с другими пользователями.например, у "Пользователя А" может быть много друзей, которые являются другими Пользователями.
Каким должно быть отображение для этого?Я думаю, что это должны быть отношения "Многие ко многим", но я действительно не знаю, как будет выглядеть HBM?
Спасибо,
Решение
Я думаю, что это должно быть много-ко-многим отношения
Вы правы.В вашем сценарии вам нужно будет использовать самореферентное сопоставление "многие ко многим".Но используя один Пользователи таблица, в которой вы не можете представить связь между Пользователи и Друзья (используя единую таблицу, вы могли бы представить самоссылочный родитель-потомок отношения).Для достижения этой цели вам понадобится промежуточная таблица.Вот пример использования SQLite - файл ADO.NET поставщик услуг чтобы показать один из возможных способов моделирования вашего сценария:
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>
Из приведенного выше сопоставления вы заметите использование следующих таблиц:Пользователи и друзья
И вот этот код:
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; }
}
}
И, наконец, для полноты картины вот мой конфигурационный файл:
<?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>