Nhibernate映射类的动态绑定

      之前遇到过想要动态加载Nhibernate实体的问题,最近在网络上找到了相应的解决办法,在这里和大家分享一下,以下是原文。


前言
  通过使用NHibernate.Mapping.Attributes命名空间中的方法,可以不用写实体类的配置hbm.xml文件,只需要在相应实体类上加上适当标签,可以较大程度的提高开发效率,减少开发时间,并且不用再为那扰人的xml而烦扰。
  1.原理
  就是通过反射查找相应对象上的标签,然后动态生成与之前对应的hbm.xml流,然后加载至Configuration中。可见通过该种方式最重要的是相应的对象上加上正确并且需要的标签。这样就可以不再写或修改那烦人的xml文件。
  2.准备工作
  必须导入NHibernate.Mapping.Attributes命名空间,该命名空间属于NHibernate.Mapping.Attributes.dll文件中,该文件在NHibernateContrib-0.9.0.0中,可以到NHibernate网站下载。本文测试所采用的NHibernate和NHibernateContrib均是在0.9.0.0上测试通过。
  3.如何加入标签
  a.class上至少需加上[ClassAttribute(Table=Children)]
   对应生成的xml片断如下
   <class name="Models.Children, Models" table="Children">
  b.Id上加上如下所示标签
   [Id(0, Name="Id",TypeType=typeof (int),Column="Id",UnsavedValue="0")]
   [Key(1)]
   [Generator(2, Class="native")]
   public int Id
   {
   get { return _id; }
   set { _id = value; }
   }
  其中0,1,2表示生成xml文件时属性的顺序,以上的标签最后生成可能是以下xml片断
   <id name="Id" column="Id" type="Int32" unsaved-value="0">
   <generator class="native" />
   </id>
  c.其他一般属性需加上如下标签
   [PropertyAttribute(Column="PName",Length=50,TypeType=typeof(String))]
   public string PName
   {
   get { return _pName; }
   set { _pName = value; }
   }
   对应xml片断
   <property name="PName" type="String" column="PName" length="50" />
  d.对于一对多情况加上如下标签
   [Bag(0,Table="Children", Lazy=true, Cascade=CascadeStyle.All)]
   [Key(1, Column="ParentId")]
   [OneToManyAttribute(2, ClassType=typeof(Children))]
   public IList Children
   {
   get { return _children; }
   set { _children = value; }
   }
   对应xml片断如下
   <bag name="Children" table="Children" lazy="true" cascade="all">
   <key column="ParentId" />
   <one-to-many class="Models.Children, Models" />
   </bag>
  e.对于多对一的情况加上如下标签
   [ManyToOne(0, ClassType=typeof (Parent),Column="ParentId",OuterJoin = OuterJoinStrategy.True)]
   public Parent Parent
   {
   get { return _parent; }
   set { _parent = value; }
   }
   对应的xml片断
   <many-to-one name="Parent" class="Models.Parent, Models" column="ParentId" outer-join="true" />
  4.类写好了,标签也加上了,可以采用如下方式加入到Configuration
   Configuration cfg = new Configuration();
   using(MemoryStream stream = new MemoryStream())
   {
   for(int i=0;i<config.Count;i++)
   {
   HbmSerializer.Serialize(stream, System.Reflection.Assembly.Load("models"));
   stream.Position = 0;
   cfg.AddInputStream(stream);
   }
   }
  4.容易出现的问题
  漏掉标签,如:在Id上漏掉Name导致Search出来的对象Id都是0,漏掉级联或是其他
  5.解决方法
  a.可以将其动态产生的xml文件流输出到一个xml文件中,然后将输出的xml文件和之前的xml文件比对容易发现问题
   输出到xml文件的代码如下:
   FileStream fs = new FileStream(@"d:/DynamicHibernateMapping.xml",FileMode.Create);
   fs.Write(stream.ToArray(),0,(Int32)stream.Length);
   fs.Close();
  b.列出一个属性标签清单,进行对比也可以
  6.其他问题
  欢迎私下交流,msn:eJimGao@msn.com
  7.Table DDL
  CREATE TABLE [dbo].[Children] (
  [Id] [int] IDENTITY (1, 1) NOT NULL ,
  [CName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
  [ParentId] [int] NULL
  ) ON [PRIMARY]
  GO
  CREATE TABLE [dbo].[Parent] (
  [Id] [int] IDENTITY (1, 1) NOT NULL ,
  [PName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL
  ) ON [PRIMARY]

 

    这里面有两点需要注意,一个是MemoryStream在使用过之后,要记得把它的Poisition置为0,因为它是一直在最后的

另一个是要对你动态生成的xml进行修改,将其中的框架信息修改为urn:nhibernate-mapping-2.2,并在结尾的地方加上"/r/n"。

有了以上这些点,你就可以动态地使用Nhibernate了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值