目录
写在前面
周一至周四一直在成都出差,也一直没有更新博客了,一回到家第一件事就是扒一扒最近博客园更新的文章,然后把想看的收藏了,大概有20篇左右,包括基础的js或者jquery(快速浏览,复习基础),java方面的(主要了解实现业务的思想),asp.net webformmvc(webform的快速浏览,mvc深入理解)等等,从昨天晚上到今天上午算是花费了7、8个小时的时间把收藏夹里面的文章看了一边。
现在就继续NHibernate系列的学习吧。
文档与系列文章
[NHibernate]持久化类(Persistent Classes)
[NHibernate]集合类(Collections)映射
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]条件查询Criteria Query
组件之依赖对象
现在有这样一个需求需要实现,我们要在Customer类中实现类似NameAddress的属性,即CustomerName=Name+Address(用名字和地址来标注一个客户的基本信息)。在Nhibernate中,可以使用dynamic-component和component快速的实现该功能。
映射文件中,<component>节点把子对象的一些属性映射为父类对应的表的一些字段。并且组件可以定义它们自己的属性、组件或者集合。
component和dynamic-component节点有如下图所示的属性:
1 <component 2 name="PropertyName" 3 class="ClassName" 4 insert="true|false" 5 upate="true|false" 6 access="field|property|nosetter|ClassName" 7 optimistic-lock="true|false" 8 <property ...../> 9 <many-to-one .... /> 10 ........ 11 </component>
access(默认property):Nhibernate用来访问属性的策略。
class(默认通过反射得到的属性类型):组件类的名字。
insert:被映射的字段是否出现在sql的insert语句中。
name:属性名字propertyName。
update:被映射的字段是否出现在sql的update语句中。
unique:是否唯一。
optimistic-lock (可选 - 默认是 true):表明更新此组件是否需要获取乐观锁。
node:节点(可选)
lazy (可选): 假若设置lazy="false",就会禁用延迟加载。
其<property>子标签为子类的一些属性与表字段之间建立映射。
<component>元素允许加入一个 <parent>子元素,在组件类内部就可以有一个指向其容器的实体的反向引用。
<dynamic-component>元素允许把一个 IDictionaryp映射为组件,其属性名对应键值
一个例子
新建一个Name类
1 /// <summary> 2 /// 描述:客户实体,数据库持久化类 3 /// 创建人:wolfy 4 /// 创建时间:2014-11-01 5 /// </summary> 6 public class Name 7 { 8 /// <summary> 9 /// 客户地址 10 /// </summary> 11 public string CustomerAddress { get; set; } 12 /// <summary> 13 /// 客户名字 14 /// </summary> 15 public string CustomerName { get; set; } 16 /// <summary> 17 /// 名字和地址 18 /// </summary> 19 public string NameAddress 20 { 21 get { return this.CustomerName + this.CustomerAddress; } 22 } 23 } 24 }
修改Customer类
1 /// <summary> 2 /// 描述:客户实体,数据库持久化类 3 /// 创建人:wolfy 4 /// 创建时间:2014-10-16 5 /// </summary> 6 public class Customer 7 { 8 /// <summary> 9 /// 客户id 10 /// </summary> 11 public virtual Guid CustomerID { get; set; } 12 /// <summary> 13 /// 客户名字 14 /// </summary> 15 public virtual Name NameAddress { get; set; } 16 /// <summary> 17 /// 版本控制 18 /// </summary> 19 public virtual int Version { get; set; } 20 }
去除Name和Address属性,修改客户名字属性为NameAddress,类型为新添加的Name类型。
修改Customer的映射文件
1 <?xml version="1.0" encoding="utf-8" ?> 2 <!--assembly:程序集,namespace:命名空间--> 3 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Wolfy.Shop.Domain" namespace="Wolfy.Shop.Domain.Entities"> 4 <class name="Wolfy.Shop.Domain.Entities.Customer,Wolfy.Shop.Domain" table="TB_Customer"> 5 <!--主键--> 6 <id name="CustomerID" type="Guid" unsaved-value="null"> 7 <column name="CustomerID" sql-type="uniqueidentifier" not-null="true" unique="true"/> 8 <generator class="assigned"></generator> 9 </id> 10 <!--版本控制--> 11 <version name="Version" column="Version" type="integer" unsaved-value="0"/> 12 <!--组件 name组件属性名--> 13 <component name="NameAddress" class="Wolfy.Shop.Domain.Entities.Name,Wolfy.Shop.Domain"> 14 <!--Name类中的属性property--> 15 <property name="CustomerName" column ="CustomerName" type="string" 16 length="16" not-null="false" /> 17 <property name ="CustomerAddress" column="CustomerAddress" type="string" 18 length="128" not-null="false" /> 19 </component> 20 </class> 21 </hibernate-mapping>
首先定义Component的一些属性,指定属性名和组件映射的类名。再使用<property>子元素,为Name类的CustomerAddress、CustomerName属性与表字段之间建立映射。
测试
1 /// <summary> 2 /// 根据客户姓名和地址查找客户信息 3 /// </summary> 4 /// <param name="strCustomerName">姓名</param> 5 /// <param name="strAddress">地址</param> 6 /// <returns>客户信息集合</returns> 7 public IList<Customer> GetCustomerAddress(string strCustomerName, string strAddress) 8 { 9 NHibernateHelper nhibernateHelper = new NHibernateHelper(); 10 //获得ISession实例 11 ISession session = nhibernateHelper.GetSession(); 12 return session.CreateQuery("from Customer as c where c.NameAddress.CustomerName=:cn and c.NameAddress.CustomerAddress=:ca") 13 .SetString("cn", strCustomerName) 14 .SetString("ca", strAddress) 15 .List<Customer>(); 16 }
查询名字为“wolfy”和地址为“北京 海淀”的客户信息
查看生成的sql
总结
通过组件可改变我们的对象模型,而数据库结构不需要变化。通过利用组件来映射依赖对象,可以非常连贯的引入NHibernate中的多表映射关系、集合等内容。参考文章:http://www.cnblogs.com/lyj/archive/2008/10/23/1317877.html