找回密码
 立即注册
首页 业界区 业界 NHibernate2.1新特性之EntityMode.Map

NHibernate2.1新特性之EntityMode.Map

辗振 2025-5-29 20:17:21
NHibernate2.1新特性之EntityMode.Map

本节内容
           
  • 引入       
  • EntityMode       
  • 典型实例
                     
    • 1.映射文件               
    • 2.Configuration配置               
    • 3.测试       
                   
  • 结语
引入

假设你想要持久化设计模型,而你不想写任何Domain实体。
假设你想在原有数据基础上测试ORM错误;而你不想写任何实体界面也没有任何实体实现。
假设朋友之间互相讨论问题,传你一些NH映射文件,来优化数据访问,但他并没有传你他的具体实现。
.........
总之,你就一堆NHibernate Mapping文件,你怎么办呢?按照映射结构试着重现Domain?还是直接放弃这些Mapping文件了?
不过我们有另外一个工具AjGenesis ,其IDE是AjGenesisStudio可以完成这项工作,但是学习成本的确高了点。
我可以告诉你,NHibernate可以做到,利用这些Mapping文件,对其测试,优化数据访问,如果你是世外高人甚至你的程序中没有Domain。
EntityMode

在NH2.1中EntityMode有三种,分别是:
           
  • POCO       
  • Dynamic-Map (又称 Dictionary)       
  • Xml
EntityMode.POCO在常见不过了,就是NHibernate默认实体模式,NHibernate按照POCO来映射实体,操作实体。事实上,我们对EntityMode.Map并不陌生,在原来映射dynamic-component中已经使用了这个功能,就是一个属性名称为键,属性值为值的字典。在NHibernate2.1中,EntityMode.Xml还未实现,就是可以映射XML文件。
EntityMode.Map也就是所谓的动态实体。
典型实例

自己构建的例子有点不“官方”,我还是从NHibernate源码中摘取一个典型的实例说明一下吧。就是一个Mapping文件,然后对Mapping文件进行测试,看这个文件是否正确!或者可以优化下映射,例如级联、二级缓存什么的。
1.映射文件

在映射文件中,要声明entity-name来代替一个类名,对于entity-name也是NHibernate2.1的一个新特性,以后再写这方面文章介绍一下。
看到这个映射文件应该很熟悉,两个Domain,双向父子关系,就是一个生产线有N个模型案例了。
  1. <class entity-name="ProductLine">
  2.     <id name="Id" type="int">
  3.         <generator class="hilo"/>
  4.     </id>
  5.     <property name="Description" not-null="true" length="200" type="string"/>
  6.     <bag name="Models" cascade="all" inverse="true">
  7.         <key column="productId"/>
  8.         <one-to-many class="Model"/>
  9.     </bag>
  10. </class>
  11. <class entity-name="Model">
  12.     <id name="Id" type="int">
  13.         <generator class="hilo"/>
  14.     </id>
  15.     <property name="Name" not-null="true" length="25" type="string"/>
  16.     <property name="Description" not-null="true" length="200" type="string"/>
  17.     <many-to-one name="ProductLine" column="productId" not-null="true" class="ProductLine"/>
  18. </class>
复制代码
2.Configuration配置

NHibernate默认设置是POCO模式。我们可以配置default_entity_mode选项设置一个默认的实体模式,这里我在这个Configuration中把default_entity_mode设置为EntityMode.Map。
  1. [TestFixtureSetUp]
  2. public void TestFixtureSetUp()
  3. {
  4.     cfg = new Configuration();
  5.     cfg.Configure();
  6.     //默认EntityMode为Poco,这里把default_entity_mode设置为EntityMode.Map
  7.     cfg.SetProperty("default_entity_mode", EntityModeHelper.ToString(EntityMode.Map));
  8.     sf = (ISessionFactoryImplementor)cfg.BuildSessionFactory();
  9. }
复制代码
3.测试

使用Dynamic-Map,就是一个字典,这里先new出来一个Hashtable的ProductLine,再new出来两个基于Hashtable的Model字典,对ProductLine保存级联保存Model。其中ISession.Save()方法也是最新增加的一重载方法,然后对其查询,最后删除测试。
  1. [Test]
  2. public void DynamicClasses()
  3. {
  4.     //一个生产线有N个模型,这里模拟汽车生产线
  5.     IDictionary cars;
  6.     IList models;
  7.     using (ISession s = sf.OpenSession())
  8.     {
  9.         using (ITransaction t = s.BeginTransaction())
  10.         {
  11.             cars = new Hashtable();
  12.             cars["Description"] = "Cars生产线";
  13.             IDictionary ferrari = new Hashtable();
  14.             ferrari["ProductLine"] = cars;
  15.             ferrari["Name"] = "Dino";
  16.             ferrari["Description"] = "法拉利Dino";
  17.             IDictionary lamborghini = new Hashtable();
  18.             lamborghini["ProductLine"] = cars;
  19.             lamborghini["Name"] = "康塔克Countach";
  20.             lamborghini["Description"] = "蓝博基尼_康塔克Countach";
  21.             models = new List<IDictionary> { ferrari, lamborghini };
  22.             cars["Models"] = models;
  23.             //第一个参数为映射中使用的实体名称,第二个参数为实例
  24.             s.Save("ProductLine", cars);
  25.             t.Commit();
  26.         }
  27.     }
  28.     using (ISession s = sf.OpenSession())
  29.     {
  30.         using (ITransaction t = s.BeginTransaction())
  31.         {
  32.             cars = (IDictionary)s
  33.                .CreateQuery("from ProductLine pl order by pl.Description")
  34.                .UniqueResult();
  35.             models = (IList)cars["Models"];
  36.             Assert.That(models.Count == 2);
  37.             s.Clear();
  38.             IList list = s.CreateQuery("from Model m").List();
  39.             var model = (IDictionary)list[0];
  40.             Assert.That(((IList)((IDictionary)model["ProductLine"])["Models"]).Contains(model));
  41.             s.Clear();
  42.             t.Commit();
  43.         }
  44.     }
  45.     using (ISession s = sf.OpenSession())
  46.     {
  47.         using (ITransaction t = s.BeginTransaction())
  48.         {
  49.             cars = (IDictionary)s
  50.               .CreateQuery("from ProductLine pl order by pl.Description")
  51.               .UniqueResult();
  52.             s.Delete(cars);
  53.             t.Commit();
  54.         }
  55.     }
  56. }
复制代码
测试结果:
第一个Session:创建对象
1.png

第二个Session:查询对象
2.png

第三个Session:删除对象
3.png

结语

当然了,我们可以利用EntityMode.Map的动态实体,把一堆没有Domain的Mapping文件进行测试,优化等操作。
我还是通过通俗易懂的语言一篇一篇来介绍NHibernate里面的秘密吧。大家对EntityMode.Map有什么好的应用,一起交流下咯。
NHibernate Q&A
           
  • 欢迎加入NHibernate中文社区,一起分享NHibernate!
希望本文对你有所帮助!

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册