编程经验 NHibernate 与数据绑定

来源:岁月联盟 编辑:zhu 时间:2008-05-21
NHibernate 为了优化性能, 提供了自己的 custom collection(ie. bag, set ...)。 当我们定义一个one-many mapping 的时候, 应当在父类里面定义IList children; 这样的一个集合(NH1.2 里面的所有集合类都实现 IList 接口 )。然而NHibernate自身提供的集合并没有implement  IBindingList , 也就是说如果我们使用NHibernate将无法实现.net 2.0 里面的complex databinding。 我想这点是NHibernate团队把 Hibernate照原样搬到.net 里来的时候所没有想到的,因为java里面没有databinding这个东东。
      怎么办呢?这问题困惑了我很久,看来只能从新写一个集合类来实现数据绑定了(实现IBindingList 的NHibernate 自定义集合类)。看起来还是蛮吓人的,就为了这个数据绑定写一个集合类。 还好我比较聪明,去网上找了一下看看有没有相关的资料, 找到了这个好东东: NHibernate.Databinding
      这是一个开源的NHibernate 扩展dll,专门为了支持complex binding做的。

具体使用方法,
      1. 先吧NHibernate.Databinding.Dll 添加到项目中。
      2. 把原有的集合类(bag) 替换成 BindingSet。
      3. 使用 BindingSet.GetInstance()  generic方法生成BindingSet的实例  (不知道为什么不用constructor, 这里应该不会是用了singleton pattern呀,奇怪)
      4. 在hbm 映像文件里面使用set 集合来指定BindingSet这个集合的类型。
      5. 在hbm 文件里面指定使用 NHibernate.Databinding.dll 里面定义的accessor (当你存取你的object的时候,此accessor类被NHibernate 用来通过反射的途径从你的object的member variable 或者property中取值或者赋值,详细可以看Hibernate文档中hbm映像文件里 对access attribute的说明。)
   
          贴一段我写的代码:
        private BindingSet<Plot> plots = BindingSet.GetInstance<Plot>();

        public BindingSet<Plot> Plots
        {
            get
            {
                return plots;
            }
        }
        Hibernate Mapping:
      <set name="Plots" cascade="all" lazy="true" inverse="true"
         access="NHibernate.DataBinding.BindingAccessor+CamelCase, NHibernate.DataBinding">
          <key column="PVAuto" />
          <one-to-many class="RWeb6.BO.FormationPressure.Plot, RWeb6.BO.FormationPressure" />
      set>

       由于NHibernate.Databinding.BindingSet 这个类实现了 IBindingList 接口,而此接口定义了ListChange事件,自此我们可以把他用来实现complex binding了!