• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
鱼要的是海洋,鸟要的是天空,我要的是自由!
平凡的人不平凡的人生
博客园    首页    新随笔    联系   管理    订阅  订阅

nhibernate入门系列 值集合映射

在数据库的多对多关系中, 实现方法是通过一个额外的关联表将两个主表关联起来,关联表中只保存两个主表的主健,显然, 主表与关联表是一对多的关系. 这样两个主表就通过这个关联表构成了一个多对多的关系.
典型的例子就是用户和权限了, 每个用户可以有多个权限, 而每个权限也可以分配给多个用户. 通过一个用户权限表就可以实现这样的要求.

因为关联表并没有其它任何信息, 所以在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对象时再载入, 这也算是延迟加载的一个变相实现吧.

posted @ 2007-01-24 01:41  伊凡  阅读(203)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3