系列文章

[Nhibernate]体系结构

[NHibernate]ISessionFactory配置

[NHibernate]持久化类(Persistent Classes)

[NHibernate]O/R Mapping基础

[NHibernate]集合类(Collections)映射 

[NHibernate]关联映射

[NHibernate]Parent/Child

[NHibernate]缓存(NHibernate.Caches)

什么是NHibernate.Mapping.Attributes?

NHibernate.Mapping.Attributes是NHibernate的附加软件,它是Pierre Henri Kuat(aka KPixel)贡献的;以前的实现者是John Morris.NHibernate需要映射信息来绑定你的域对象到数据库。通常他们被写在(并且被保存在)分散的hbm.xml文件里。

使用NHibernate.Mapping.Attributes,你可以使用.NET属性(attributes)来修饰你的实体和被用于产生.hbm.xml映射(文件或者流)的属性(attributes).因此,你将不再会为这些令人厌恶的文件而烦恼。

这个库里面的内容包括:

  • NHibernate.Mapping.Attributes:你需要的唯一工程(作为最终用户)。
  • Test一个使用属性(attributes)和HbmSerializer的简单用例,是NUnit的TestFixture。
  • Genaerator:用来产生属性(attributes)和HbmWriter的程序。
  • Refly:感谢Jonathan de Halleux提供这个库,它使的产生代码变得如此简单。

重要提示

这个库是使用文件/src/NHibernate.Mapping.Attributes/nhibernate-mapping-2.0.xsd(它嵌入在程序集中能检查产生的xml流的合法性)产生的,这个文件可能在NHibernate每次发布新版本时发生变化,所以你应该在不同的版本中使用它时,重新生成它(打开Generator工程,编译并且运行Generator项目)。但是,在0.8之前的版本中它并没有通过测试。

如何使用?

最终用户类 是NHibernate.Mapping.Attributes.HbmSerializer.这个类序列化你的域模型到映射流.你可以逐个序列化程序集中的类.NHibernate.Mapping.Attributes.Test可以作为参考.
第一步用属性(attributes)修饰你的实体;你可以用 [Class], [Subclass], [JoinedSubclass]或者[Component].然后,修饰成员(字段/属性properties);它们能够代替很多映射中需要使用的属性(attributes ),例如:

1 [NHibernate.Mapping.Attributes.Class]
2     public class Example
3     {
4         [NHibernate.Mapping.Attributes.Property]
5         public string Name;
6     }

完成这个步骤后,使用NHibernate.Mapping.Attributes.HbmSerializer:(这里我们使用了Default ,它是一个实例,在你不必须/不想自己创建它时使用).

 1  System.IO.MemoryStream stream = new System.IO.MemoryStream(); // where the xml will be written
 2     NHibernate.Mapping.Attributes.HbmSerializer.Default.Validate = true; // Enable validation (可选)
 3     // Here, we serialize all decorated classes (but you can also do it class by class)
 4     NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize(
 5         stream, System.Reflection.Assembly.GetExecutingAssembly() );
 6     stream.Position = 0; // Rewind
 7     NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
 8     cfg.Configure();
 9     cfg.AddInputStream(stream); // Use the stream here
10     stream.Close();
11     // Now you can use this configuration to build your SessionFactory...

注意:正如你所见:NHibernate.Mapping.Attributes是没有(真正的)侵入性的.在你的对象上设置属性(attributes ),不会强迫你在NHibernate 使用它们,并且不会破坏你的架构体系中的任何约束.属性(Attributes)仅仅是纯粹的信息.

提示

  • 使用HbmSerializer.Validate来启用/禁用产生的xml流的合法性检查(依靠NHibernate mapping schema);对于快速查找问题这是很有用的(它们被StringBuilder写入HbmSerializer.Error).如果错误是这个库预期的,库会看它是否是已知的问题并且报告它;解决这些问题能帮助你完成你的解决方案. :)
  • 你的类,字段和属性properties(成员)可以是私有的;请确认你有使用反射访问私有成员的权限(ReflectionPermissionFlag.MemberAccess).
  • 映射类的成员也会在基类中查找(直到找到映射的基类).因此,你可以在基类(没有做映射)中修饰成员,然后在它的(做过映射的)子类中使用它.
  • 对于一个有类型(System.Type)的Name,使用Name="xxx"(作为string)设置类型或者设置NameType=typeof(xxx);(给 "Name"添加"类型")
  • 默认情况下,.NET属性(attributes)没有维持属性(attributes)的顺序;因此,你必须自己设置顺序,在你管理顺序的时候(使用每个属性的第一个参数).强烈推荐设置它,当你的一个成员上有超过一个属性(attribute )时.
  • 只要不产生含糊,你可以在成员上定义很多不相干的属性(attributes).一个好的例子是在标识符成员上的类描述(class-related)属性(attributes )(类似鉴别器<discriminator>).但是不要忘记管理顺序(<discriminator> 必须在<id>的后面).顺序来自NHibernate mapping schema中元素(elements)的顺序.在我个人看来,我更喜欢在属性上使用负数(如果它们是在前面的!).
  • 你可以在类上面加 [HibernateMapping] 来指定<hibernate-mapping> 属性(attributes)(当类被序列化成流时使用).你也可以使用HbmSerializer.Hbm*属性(properties)(当被[HibernateMapping]修饰的类型或程序集被序列化时被使用).
  • 不使用一个字符串作为鉴别器值(DiscriminatorValue)(在[Class]和[Subclass]),你可以在任何你需要的对象上这样使用.例子: [Subclass(DiscriminatorValueEnumFormat="d", DiscriminatorValueObject=DiscEnum.Val1)]

在这里,对象是一个枚举,你可以设置你需要的格式(默认的值是"g").注意你必须把它放在前面!对于其他的类型,只是简单的使用了对象的ToString()方法.

  • 如果你使用Nullables.NullableXXX类型的的成员(在库Nullables中),系统会自动映射到Nullables.NHibernate.NullableXXXType;不用在[Property]中设置Type="..."(让它为空).感谢Michael Third的这个主意. :)
  • NHibernate.Mapping.Attributes产生的每个流都有一个产生日期的注释;你可以通过方法WriteDateComment启用/禁用它.
  • 如果你忘记提供一个必须的xml属性(attribute),系统会抛出一个异常,在创建映射时.
  • 映射[Component] 时,被推荐的并且最简单的方式是使用[ComponentProperty].

首先,放置[Component]在组件类并且映射它的字段/属性.注意不要在[Component]设置名字.然后,在你的类的每个成员,添加[ComponentProperty].但是你不能改变每个成员的存取(Access),更新(Update)或插入(Insert).
在NHibernate.Mapping.Attributes.Test里有一个例子(注意CompAddress类和他在其他类中的使用).
注意最后一件事情:ComponentPropertyAttribute是从DynamicComponentAttribute继承来的,容易把它紧接着写在 <component>元素的后面,在XML流中.

  • 另一个映射[Component]的方式是,它用这种方法让库工作:如果一个类包含了一个组件映射,那么这个组件将会被类包含.NHibernate.Mapping.Attributes.Test包含JoinedBaz和Stuff使用地址(Address)组件的例子. 很简单的,添加了以后 [Component(Name = "MyComp")] private class SubComp : Comp {}
  • 在所有类中,一个优势是能够改变每个成员的存取(Access),更新(Update)或插入(Insert).但是,你必须添加组件子类到每个类中(并且它不能被继承).
  • 关于自定义。HbmSerializer使用HbmWriter序列化各种属性(attributes)。他的方法是虚的;因此你可以创建一个子类,重写任何方法(来改变它的默认行为)。

使用属性(property)HbmSerializer.HbmWriter来改变写的实现者。(你可以设置一个HbmWriter的子类)。使用了部分提示的例子:(0,1和2按顺序排列)

1  [NHibernate.Mapping.Attributes.Id(0, TypeType=typeof(int))] // Don't put it after [ManyToOne] !!!
2         [NHibernate.Mapping.Attributes.Generator(1, Class="uuid.hex")]
3     [NHibernate.Mapping.Attributes.ManyToOne(2, ClassType=typeof(Foo), OuterJoin=OuterJoinStrategy.True)]
4     private Foo Entity;

产生的:

1  <id type="Int32">
2         <generator class="uuid.hex" />
3     </id>
4     <many-to-one name="Entity" class="Namespaces.Foo, SampleAssembly" outer-join="true" />

已知的问题和TODOs

首先,阅读源代码里面的TODOs

Position属性(property)被加在所有属性(attributes)上,用来给他们排序。但是仍然有问题:

当一个父元素"p"有一个子元素"x",它的另一个子元素"c"有子元素"x"。:D 如

1  <p>
2         <c>
3             <x />
4         </c>
5         <x />
6     </p>

在这个例子中,如果这样写:

1  [Attributes.P(0)]
2         [Attributes.C(1)]
3             [Attributes.X(2)]
4         [Attributes.X(3)]
5     public MyType MyProperty;

X(3)将会属于C(1)!(和X(2)一样)

下面是<dynamic-component>和<nested-composite-element>的情况。

另一个坏消息是,现在,后来加入的XML元素不能被包含.例如:没有办法在<dynamic-component>放置集合.原因是nhibernate-mapping-2.0.xsd文件告诉程序元素怎么被创建,按照什么顺序被创建,并且NHibernate.Mapping.Attributes按这个顺序使用它们.

总之,解决方案应该添加整型的ParentNode属性(property)给BaseAttribute,这样你能够创建一个真实的情况...

实际上,没有其他的知识点了而且也没有计划好的修改.这个库将会成为稳定的完整版本;但是你发现了问题或者有有效的改进想法,请联系我们!

另一个消息,希望有比NHibernate.Mapping.Attributes.Test更好的TestFixture.:D

开发者须知

schema (nhibernate-mapping-2.0.xsd)的任何改变意味着:

  • 检查是否要在Generator中做任何改变(象updating KnowEnums / AllowMultipleValue / IsRoot / IsSystemType / IsSystemEnum / CanContainItself)
  • 更新/src/NHibernate.Mapping.Attributes/nhibernate-mapping-2.0.xsd (复制/粘贴),并且再次运行Generator(即使你没有修改)
  • 运行测试项目,确定没有已知的异常抛出.应该在可以确保能够把握改变带来的破坏时,修改/添加这个项目中一个类/属性(property)(=>更新hbm.xml文件和/或NHibernate.Mapping.Attributes-1.1.csproj项目的引用)

这个实现基于NHibernate mapping schema;有可能很多"标准schema特性"没有被支持...
这个版本的NHibernate.Mapping.Attributes需要使用NHibernate库的版本的schema来产生.
这个项目的设计,性能是一个(十分)小的目标,实现和维护则要重要许多.

本文来自《NHibernate 中文文档》

转载于:https://www.cnblogs.com/wolf-sun/p/3733929.html

[NHibernate]使用AttributeNHibernate.Mapping.Attributes相关推荐

  1. NHibernate剖析:Mapping篇之Mapping-By-Code(1):概览

    ModelMapper概述 NHibernate3.2版本号集成Mapping-By-Code(代码映射),其设计思想来源于ConfORM.代码总体构思基于"Loquacious" ...

  2. 使用NHibernate 3.2实现Repository(ORuM)(三)NHibernate、Mapping、Mapping-By-Code

    NHibernate使用时通常是先定义实体类,再为实体类映射数据库关系,NHibernate映射是使用XML文件形式的. 当我们Confrontation NHibernate时Mapping的过程: ...

  3. nHibernate Mapping By Code - Introduction

    nHibernate 3.2新增了一种mapping by code的映射策略,很有意思.你可以自定义约定,并且按照约定定制自动映射策略,面对遗留数据库时这个功能往往很有用,另外,由于mapping ...

  4. NHibernate重要概念的解释和说明

    NHibernate 是一个面向.NET环境的对象/关系数据库映射工具. 对象/关系数据库映射(object/relational mapping (ORM)) 这个术语表示一种技术,用来把对象模型表 ...

  5. [NHibernate]代码生成器的使用

    目录 写在前面 文档与系列文章 代码生成器的使用 总结 写在前面 前面的文章介绍了nhibernate的相关知识,都是自己手敲的代码,有时候显得特别的麻烦,比如你必须编写持久化类,映射文件等等,举得例 ...

  6. 推荐NHibernate新书:NHibernate 3.0 CookBook[附下载]

    NHibernate 3.0 CookBook这本书在2010年10月4号出版,出版后NHibernate的Lead:Fabio Maulo赠送我一份免费优惠券,我花了几天时间阅读了这本电子书,以下是 ...

  7. [Nhibernate]对象状态

    目录 写在前面 文档与系列文章 对象状态 瞬时态(Transient) 持久态(Persistent) 脱管态(Detached) 对象状态转换 总结 写在前面 前面两篇文章介绍了SchemaExpo ...

  8. NHibernate 基本配置 (第一篇)

    使用NHibernate最重要的一步就是配置,如果连NHibernate都还没有跑的起来,谈何学习.今天就来详解一下NHibernate的配置. 一.NHibernate基本配置 NHibernate ...

  9. [NHibernate]基本配置与测试

    目录 写在前面 nhibernate文档 搭建项目 映射文件 持久化类 辅助类 数据库设计与连接配置 测试 总结 写在前面 一年前刚来这家公司,发现项目中使用的ORM是Nhibernate,这个之前确 ...

最新文章

  1. Delphi_04_Delphi_Object_Pascal_基本语法_02
  2. C++实现对链表的选择排序算法(附完整源码)
  3. 在word文档里提取出所有的邮箱地址
  4. rtk采点后如何导入cad_【干货】RTK实操视频:工程之星5.0操作攻略!(第五部分)...
  5. DPDK examples ethtool-app完全注释
  6. SQL Server 2008将数据导出到SQL脚本文件
  7. target is busy / device is busy 设备无法取消挂载问题处理
  8. php api权限,如何设计RESTful的API权限
  9. CSP202104-4 校门外的树
  10. 澳洲墨尔本大学的计算机专业,墨尔本大学计算机专业排名澳洲第一,申请条件又有变化了!...
  11. 【第二周】吴恩达团队AI for Medical Diagnosis大作业
  12. 计算机系统引导失败怎么办,电脑开机出现引导失败怎么办 是什么原因造成的...
  13. Win10 wusa命令卸载系统更新
  14. 【BZOJ1791】【IOI2008】【基环树】island(status第一速度)
  15. 2022年安全员-A证考题及在线模拟考试
  16. Python 还原控制SCI论文算法系列1: 基于策略迭代的自适应最优控制器设计
  17. 如何打开.pkl文件,查看.pkl文件里的内容(Python3.6)
  18. 机器学习笔记 - 用于颜值评分的数据集和算法
  19. 【实战】OpenCV+Python项目实战--文档扫描OCR识别
  20. Java基于nfs-client包实现NFS协议连接linux服务器进行文件上传与下载操作源码

热门文章

  1. 黑马程序员--java基础知识注意点收录
  2. [翻译]The Data Access Application Block
  3. java(22) - 异常详解
  4. Android编程之指定ListView的item位置
  5. Android笔记之权限库AndPermission
  6. 20.1 shell脚本介绍 20.2 shell脚本结构和执行 20.3 date命令用法 20.4 shell脚本中的变量...
  7. php7扩展安装奇葩事
  8. 获取 python import模块的路径
  9. 全球以太网交换机和路由器市场:谁领跑?
  10. 去除Android 6.0 界面下的导航栏:NavigationBar