[转]NHibernate之旅(8):巧用组件之依赖对象
本节内容
- 引入
- 方案1:直接添加
- 方案2:巧用组件
- 实例分析
- 结语
引入
通过前面7篇的学习,有点乏味了~~~这篇来学习一个技巧,大家一起想想如果我要在Customer类中实现一个Fullname属性(就是Firstname和Lastname的组合)该怎么做呢?
方案1:直接添加
“我知道!修改Customer类,添加一个Fullname属性!即Customer.Fullname!”
“恩,完全正确......”
“这就意味着在Customer类中把Firstname和Lastname两个属性重新修改组合为Fullname属性。这样的话,如果有其它的类(像Vendor、Shiper)使用了Firstname和Lastname两个属性,这就需要修改很多业务逻辑。那你的麻烦可就大了,还有什么方法吗?”
“.........”
方案2:巧用组件
NHibernate中,提供了组件(Component)和动态组件来帮助我们完成这件事情。其实组件在NHibernate中为了不同目的被重复使用。这里我们使用它来依赖对象。
映射文件中,<component>元素把子对象的一些属性映射为父类对应的表的一些字段。然后,组件可以定义它们自己的属性、组件或者集合。
下面用两幅图显示组件和动态组件两个节点映射属性:
看看这些映射属性:
- access(默认property):NHibernate用来访问属性的策略
- class(默认通过反射得到的属性类型):组件(子)类的名字
- insert:被映射的字段是否出现在SQL的INSERT语句中
- name:属性名propertyName
- update:被映射的字段是否出现在SQL的UPDATE语句中
- <property>子元素:为组件(子)类的一些属性与表字段之间建立映射
- <parent>子元素:在组件类内部就可以有一个指向其容器的实体的反向引用
<dynamic-component>元素允许一个IDictionary作为组件映射,其中属性名对应字典中的键。这又是使用组件的另一种用法。
知道上面的知识,我们该想想上面的问题该如何利用组件来实现了吧。
实例分析
我们用一幅图来展示我们这节所说的一切:
开始动手吧!
1.新建Name类
namespace DomainModel.Entities
{
public class Name
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Fullname
{
get
{
return Firstname + " " + Lastname;
}
}
}
}
简单的说,这个类用于组合Fullname属性。
2.修改Customer类
namespace DomainModel.Entities
{
public class Customer
{
public virtual int CustomerId { get; set; }
public virtual int Version { get; set; }
public virtual Name Name { get; set; }
}
}
修改Customer类,去除原来的Firstname和Lastname属性,添加Name属性。这时Name作为Customer的一个组成部分。需要注意的是:和原来Firstname和Lastname属性一样,需要对Name的持久化属性定义getter和setter方法,但不需要实现任何的接口或声明标识符字段。
3.修改Customer映射
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="DomainModel" namespace="DomainModel">
<class name ="DomainModel.Entities.Customer,DomainModel" table="Customer">
<id name="CustomerId" column="CustomerId" type="Int32" unsaved-value="0">
<generator class ="native"></generator>
</id>
<version name="Version" column="Version" type="integer" unsaved-value="0"/>
<component name="Name" class="DomainModel.Entities.Name,DomainModel">
<property name="Firstname" column ="Firstname" type="string"
length="50" not-null="false" unique-key="UC_CustomerName"/>
<property name ="Lastname" column="Lastname" type="string"
length="50" not-null="false" unique-key="UC_CustomerName"/>
</component>
</class>
</hibernate-mapping>
首先定义Component的一些属性,指定属性名和组件映射的类名。再使用<property>子元素,为Name类的Firstname、Lastname属性与表字段之间建立映射。是不是很简单~~
这时Customer表中还是CustomerId、Version、Firstname、Lastname字段。完全不需要修改数据库表结构哦。
这里需要注意两点:
- 就像所有的值类型一样,组件不支持共享引用。组件的值为空从语义学上来讲是专有的。每当重新加载一个包含组件的对象,如果组件的所有字段为空,那么NHibernate将假定整个组件为空。对于绝大多数目的,这样假定是没有问题的。
- 组件的属性可以是NHibernate类型(包括集合、多对一关联以及其它组件)。嵌套组件不应该作为特殊的应用被考虑。NHibernate趋向于支持设计细粒度的对象模型。
4.编写方法
这时,我们需要修改或者重新编写新的方法来实现我们想要的逻辑。
public IList<Customer> ReturnFullName(string firstname, string lastname)
{
return _session
.CreateQuery("select from Customer c where c.Name.Firstname=:fn and c.Name.Lastname=:ln")
.SetString("fn", firstname)
.SetString("ln", lastname)
.List<Customer>();
}
现在,我们访问Customer的Firstname、Lastname属性,只需要在原来的基础上通过Name访问,例如上面修改的情况,看看上面图片上怎么访问的吧,一目了然。
如果我们要添加一个Customer怎么办呢?代码片段如下所示:
var customer = new Customer() { Name = new Name() { Firstname = "YJing", Lastname = "Lee" } };
5.测试方法
有了上面的方法,我们编写一个测试用例测试一下这个方法吧:看看结果测试成功,OK。
[Test]
public void ReturnFullNameTest()
{
IList<Customer> customers = _relation.ReturnFullName("YJing","Lee");
foreach (Customer c in customers)
{
Assert.AreEqual("YJing Lee", c.Name.Fullname);
}
}
结语
这一篇像大家介绍一个使用组件技巧,通过组件可以改善我们的对象模型,而数据库结构不需要变化。通过这一篇的技巧,利用组件来映射来依赖对象,可以非常连贯的引入NHibernate中的多表映射关系、集合等内容,这些才是NHibernate中的亮点,就连LINQ都比不过它。从下篇开始就来学习NHibernate中的闪光点。
[转]NHibernate之旅(8):巧用组件之依赖对象的更多相关文章
- NHibernate之旅(8):巧用组件之依赖对象
本节内容 引入 方案1:直接加入 方案2:巧用组件 实例分析 结语 引入 通过前面7篇的学习,有点乏味了~~~这篇来学习一个技巧.大家一起想想假设我要在Customer类中实现一个Fullname属性 ...
- [NHibernate]组件之依赖对象
目录 写在前面 文档与系列文章 组件之依赖对象 一个例子 总结 写在前面 周一至周四一直在成都出差,也一直没有更新博客了,一回到家第一件事就是扒一扒最近博客园更新的文章,然后把想看的收藏了,大概有20 ...
- NHibernate之旅系列文章导航
NHibernate之旅系列文章导航 宣传语 NHibernate.NHibernate教程.NHibernate入门.NHibernate下载.NHibernate教程中文版.NHibernate实 ...
- NHibernate教程(8)--巧用组件
本节内容 引入 方案1:直接添加 方案2:巧用组件 实例分析 结语 引入 通过前面7篇的学习,有点乏味了~~~这篇来学习一个技巧,大家一起想想如果我要在Customer类中实现一个Fullname属性 ...
- 基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用
大概一年前,我还在用Asp.NET开发一些行业管理系统的时候,就曾经使用这个组件作为文件的上传操作,在随笔<Web开发中的文件上传组件uploadify的使用>中可以看到,Asp.NET中 ...
- Fluent NHibernate之旅
Fluent NHibernate 之旅 导航篇: [原创]Fluent NHibernate之旅开篇: [原创]Fluent NHibernate之旅二--Entity Mapping: [原创]F ...
- NHibernate之旅(18):初探代码生成工具使用
本节内容 引入 代码生成工具 结语 引入 我们花了大量的篇幅介绍了相关NHibernate的知识.一直都是带着大家手动编写代码,首先创建数据库架构.然后编写持久化类和映射文件,最后编写数据操作方法.測 ...
- [转]NHibernate之旅(13):初探立即加载机制
本节内容 引入 立即加载 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过上一篇的介绍,我们知道了NHibernate中默认的加载机制——延迟加载.其本质就是使用GoF23中代理模式 ...
- NHibernate之旅(13):初探马上载入机制
本节内容 引入 马上载入 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过上一篇的介绍,我们知道了NHibernate中默认的载入机制--延迟载入.其本质就是使用GoF23中代理模式 ...
随机推荐
- objective-c在Xcode中@property相关参数的解释
objective-c在其对象拥有成员变量时,我们为了保持代码的封装,会将成员变量设置为@protected,并为成员变量编写setter和getter方法. 如: @interface Person ...
- Javascript 数组自定义排序,并获取排序后的保存原索引的同序数组(堆排序实现)
比如数组A: [ 0: 5, 1: 2, 2: 4, 3: 3, 4: 1 ] 排序后的结果为:[1, 2, 3, 4, 5],但是有时候会有需求想要保留排序前的位置到一个同位数组里,如前例则为:[4 ...
- 苹果ios、ipad加密视频播放器使用教程
操作流程 温馨提示 播放时,请务必保证播放设备联网(原因:用户名权限验证需要网络,播放后10秒即可关闭网络) a) 请在苹果商店下载并安装app播放器:DrmPlayer b) 选择已 ...
- 入门2:PHP相关的名词解释
/**宝宝我英语不好,后面注释拼音 请见谅**/ 1.Linux 开源的操作系统,在服务器端用户数量非常大,很多服务器都是使用Linux系统运行的. 相对windows系统来说具有非常完善的用户权限系 ...
- ionic移动开发入门
学习资料:http://www.ionic.wang http://www.ionicframework.com/
- GitHub使用教程for Eclipse
1.下载egit插件http://www.eclipse.org/egit/ http://www.eclipse.org/egit/download/ Installing the Latest R ...
- mongodb篇二:mongodb克隆远程数据库,去重查询的命令及对应java语句
http://blog.csdn.net/qkxh320/article/details/16115671 1.首先操作mongodb最基本命令:: show databases; ...
- linux的getcwd和readlink的区别
针对linux下的程序,有两个路径: 1>运行程序的路径; 2>可执行文件所在的路径 例如: 如果我在/home/yongchao下执行 $ ./temp/test 那么 运行程序的 ...
- 关于优化C#程序的五十种方法
一.用属性代替可访问的字段 1..NET数据绑定只支持数据绑定,使用属性可以获得数据绑定的好处: 2.在属性的get和set访问器重可使用lock添加多线程的支持. 二.readonly(运行时常量) ...
- 可爱的PYTHON,更新到0.5版本代码
这书看得挺顺的. 按着思路学习软件开发的主流思想.. cdctools.py # _*_ coding: utf-8 _*_ import os,sys def cdWalker(CDROM, cdc ...