nhibernate - 如何使用多对多将 NHibernate 从表 A 映射到表 A 本身?

标签 nhibernate nhibernate-mapping

求助!我不知道如何映射以下情况:

我只有一张 table 。

[Table] User { id, name }

我的类(class)是这样的

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

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

每个用户都与其他用户有关系。例如,'用户 A' 可以有很多 friend ,也就是其他用户。

这个映射应该是什么?我认为这应该是多对多关系,但我真的不知道 HBM 会是什么样子?

谢谢,

最佳答案

I think this should be Many-to-Many relationship

你是对的。在您的场景中,您将需要使用自引用的多对多映射。但是使用单个 Users 表不能表示 usersfriends 之间的关系(使用单个表可以表示自引用 parent-child 关系).您将需要一个中间表来实现此目的。下面是一个使用 SQLite ADO.NET provider 的示例,展示了一种可能的场景建模方法:

用户.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>

从上面的映射中,您会注意到以下表的使用:用户和 friend

代码如下:

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>

关于nhibernate - 如何使用多对多将 NHibernate 从表 A 映射到表 A 本身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/401207/

相关文章:

nhibernate - 从多个程序集映射

nhibernate - 如何在NHibernate中与null建立一对一的关系?

c# - NHibernate 正在生成连接错误的 SQL

c# - NHibernate 的独立 Hello World 类型示例

NHibernate QueryOver 对每个一对多集合进行排序

NHibernate Session.SetReadOnly

c# - NHibernate ISession.save(newTransientEntity) 是否只会返回生成的 Id,但不会更新实体的 Id 属性?

java - Spring+hibernate java.lang.StackOverflowError

xml - Fluent NHibernate 和 XML 列

nhibernate - 连接两个非关键字段