NHibernate.3.0.Cookbook第三章第10节的翻译

Using dictionaries as entities

使用字典作为实体

  NHibernate中一个鲜为人知的特性是EntityMode.Map. 本节介绍如何使用该特性来持久化实体,而不是使用类.

准备

为NHibernate创建一个控制台应用程序,步骤如下:
1.   创建一个控制台应用程序.
2.   添加引用NHibernate.dll,NHibernate.ByteCode.Castle.dll.

3.   在Main函数中添加下面的代码:

View Code
var nhConfig = new Configuration().Configure();
var sessionFactory = nhConfig.BuildSessionFactory();

4.   在项目中添加App.config文件.
5.   在configuration 元素中,声明hibernate-configuration节点,代码如下:

View Code
<configSections>
  <section name="hibernate-configuration"
           type="NHibernate.Cfg.ConfigurationSectionHandler,
NHibernate"/>
</configSections>

6.   在configuration 元素中,添加名为db的连接字符串,代码如下:

View Code
<connectionStrings>
    <add name="db" connectionString="Server=.\SQLExpress;
Database=NHCookbook; Trusted_Connection=SSPI"/>
  </connectionStrings>

7.   添加hibernate-configuration节点节点,代码如下:

View Code
<hibernate-configuration
xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
  <property name="proxyfactory.factory_class">
  NHibernate.ByteCode.Castle.ProxyFactoryFactory,
  NHibernate.ByteCode.Castle
  </property>
  <property name="dialect">
  NHibernate.Dialect.MsSql2008Dialect,
  NHibernate
  </property>
  <property name="connection.connection_string_name">
  db
  </property>
  <property name="adonet.batch_size">
  100
  </property>
  <mapping assembly="yourAssemblyHere"/>
</session-factory>
</hibernate-configuration>

8.   将映射程序集的值改为项目的名字.

步骤

1.   在hibernate-configurationn节点的session-factory元素中,添加值为dynamic-map的default_entity_mode属性.
2.   新建一个映射文件Product.hbm.xml,代码如下:

View Code
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class entity-name="Product"
         discriminator-value="Eg.Core.Product">
    <id name="Id" type="Guid">
      <generator class="guid.comb" />
    </id>
    <discriminator column="ProductType" type="String" />
    <natural-id mutable="true">
      <property name="Name" not-null="true"
                type="String" />
    </natural-id>
    <version name="Version" type="Int32"/>
    <property name="Description" type="String" />
    <property name="UnitPrice" not-null="true"
              type="Currency" />
  </class>
</hibernate-mapping>

3.   再创建一个映射文件Movie.hbm.xml,代码如下:

View Code
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <subclass entity-name="Movie" extends="Product"
            discriminator-value="Eg.Core.Movie">
    <property name="Director" type="String" />
    <list name="Actors" cascade="all-delete-orphan">
      <key column="MovieId" />
      <index column="ActorIndex" />
      <one-to-many entity-name="ActorRole"/>
    </list>
  </subclass>
</hibernate-mapping>

4.   最后,再创建一个映射文件ActorRole.hbm.xml,代码如下:

View Code
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class entity-name="ActorRole">

    <id name="Id" type="Guid">
      <generator class="guid.comb" />
    </id>
    <version name="Version" type="Int32" />
    <property name="Actor" type="String"
              not-null="true" />
    <property name="Role" type="String"
              not-null="true" />
  </class>
</hibernate-mapping>

5.   将这些映射文件设置为嵌入式资源.
6.   在Main函数中,构建session factory之后,创建一个movie对象作为字典,代码如下:

View Code
var movieActors = new List<Dictionary<string, object>>()
{
  new Dictionary<string, object>() {
  {"Actor","Keanu Reeves"},
  {"Role","Neo"}
  },
  new Dictionary<string, object>() {
  {"Actor", "Carrie-Ann Moss"},
  {"Role", "Trinity"}
  }
};
var movie = new Dictionary<string, object>()
{
  {"Name", "The Matrix"},
  {"Description", "Sci-Fi Action film"},
  {"UnitPrice", 18.99M},
  {"Director", "Wachowski Brothers"},
  {"Actors", movieActors}
};

7.   创建movie字典后,将其保存,代码如下:

View Code
using (var session = sessionFactory.OpenSession())
{
  using (var tx = session.BeginTransaction())
  {
  session.Save("Movie", movie);
  tx.Commit();
  }
}

8.   编译运行.
9.   查看数据库的Product表,ActorRole表.

原理

  EntityMode.Map映射允许将实体定义为词典而不再是静态类型. 这种方法分为三个部分.
  首先,First, 不再使用默认的EntityMode.Poco来创建会话,使用默认的EntityMode.Poco时,使用类对象和NHibernate进行交互.现在我们使用EntityMode.Map,通过设置default_entity_mode属性的值为dynamic-map来实现.在第一章中,我们了解到,NHibernate来源于Java的Hibernate,NHibernate使用术语map来代替dictionary.
  其次,我们对映射做一些微小的改变.首先,你会注意到,我们设置一个entity-name而不是一个class name.这使得我们可以通过名称来指定一个实体,而不在让NHibernate基于我们传入的对象类型来决定. 然后,你会注意到,我们为所有的属性指定了类型,因为我们不再有类,NHibernate也再能通过类来推测我们的数据类型,所以我们必须告诉她.最后,我们指定了discriminator值.记得在第二章中,默认的discriminator值是类型的全名.默认的discriminator值实际上是entity-name(她默认的就是类型的全名).本节中,没有了类型,如果仍旧使用entity-names会造成数据和映射无法匹配.我们覆盖了值,只是为了数据可以完美匹配来自其他示例的数据.
  最后,我们使用dictionaries (maps)和entity-name字符串来关联会话,而不在使用带类型的对象.

扩展

  虽然这个例子可能看起来有点学术,但随着Dynamic Language Runtime的发布和C#4中新的动态特性,在连接NHibernate和动态语言上,这种类型的应用无疑是很有用的.

Partially dynamic(部分动态)

  在整个应用程序中很少需要使用EntityMode.Map,如本节示例所示.但是,在一些特殊的情况下,你或许需要使用她,比如在你不想创建类时.在这样的情况下,我们不在设置default_entity_mode属性,而会在map模式中打开一个子会话.实现的代码,如下所示:

View Code
using (var pocoSession = sessionFactory.OpenSession())
{
  using (var childSession =

  pocoSession.GetSession(EntityMode.Map))
  {
    // Do something here
  }
}

转载于:https://www.cnblogs.com/carfieldSE/archive/2012/07/16/2592050.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值