NHibernate應用 many-to-many

來源:互聯網
上載者:User

在資料庫的多對多關係中, 實現方法是通過一個額外的關聯表將兩個主表關聯起來,關聯表中只儲存兩個主表的主健,顯然, 主表與關聯表是一對多的關係. 這樣兩個主表就通過這個關聯表構成了一個多對多的關係.
典型的例子就是使用者和許可權了, 每個使用者可以有多個許可權, 而每個許可權也可以分配給多個使用者. 通過一個使用者權限表就可以實現這樣的要求.

因為關聯表並沒有其它任何資訊, 所以在NH中它不能算是一個持久對象, 沒必要像處理one-to-many的情況那樣.在NH中, 通過值集合映射來處理這種情況.

下面以使用者/許可權為例再看看實際的處理情況.

測試代碼

[Test]
public void TestUserPermission() {
   User u = new User();
   u.Name = "test name";
   u.Password = "test password";
   u.AddPermission( 10 );

   session.Save(u);
   session.Close();

   User u2 = session.Load( typeof(User), u.UserId );
   Assertion.AssertNotNull( "add permission fail!", u2.Permissions[ 10 ] );

   u2.AddPermission( 20 );
   u2.RemovePermission( 10 );

   session.Save(u2);
   session.Close();

   User u3 = session.Load( typeof(User), u.UserId );
   Assertion.AssertNull( "remove permission fail!", u3.Permission[ 10 ] );
   Assertion.AssertNotNull( "add permission fail!", u3.Permission[ 20 ] );
}
以上測試代碼中session的相關操作請查看相關文檔。
在這裡給User類定義了兩個操作許可權的方法: AddPermission和RemovePermission.

類定義

public class User {

   public User() {
   }

   public void AddPermission( int permissionId ) {
      permissions[ permissionId ] = dummyObject;
   }

   public void RemovePermission( int permissionId ) {
      permissions.Remove( permissionId );
   }

   #region O/R Mapping Fields.

   private int userId;
   public int UserId
   {
      get { return userId; }
      set { userId = value; }
   }

   private string name;
   public string Name
   {
      get { return name; }
      set { name = value; }
   }

   private string password;
   public string Password
   {
      get { return password; }
      set { password = value; }
   }

   private IDictionary permissions = new Hashtable();
   public IDictionary Permissions
   {
      get { return permissions; }
      set { permissions = value; }
   }

   #endregion

   private readonly object dummyObject = new object();
}
在User類中,定義了一個Permissions集合用來儲存使用者的許可權. 因為使用了IDictionary, 所以也定義了一個啞對象.

對應檔

<class name="User, AssemblyName " table="Users">
   <id name="UserId" column="user_id" type="Int32" unsaved-value="0">
      <generator class="identity"/>
   </id>

   <property name="Name" column="name" type="String"/>
   <property name="Password" column="password" type="String"/>

   <set name="Permissions" table="UserPermissions">
      <key column="user_id"/>
      <element column="permission_id" type="Int32"/>
   </set>
</class>
在set定義中, 指定值集合的名稱,以及關聯表的名稱, 再指定key值, 也即在關聯表的健, 一般是主健.
element元素指定產生值集合的列和類型.

值集合的開銷遠小於對象集合的開銷, 在有些時候, 可以考慮將one-to-many簡化為集集合, 這樣我們只取得many的id值, 在需要訪問many對象時再載入, 這也算是消極式載入的一個變相實現吧.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.