使用Spring.Net 1.3.2 + NHibernate 3.2的mapping by code和default convention

NH的官网今天出了两篇blog,讲如何使用NH3.2的mapping by code,不过都弱爆了,推荐直接看Fabio Maulo的blog去(一、二)
简单的说,NH的mapping by code有三种方式
  • 直接为每个entity类调用ModelMapper.Class方法
  • Conformist映射,也就是class by class
  • Convention,当然约定是可以被explicit mapping所覆盖的
本文展示第二三种混合的方式,也就是使用convention,然后覆盖。
 
首先,使用Convention
NH3.2中,使用Convention的方法也有两种,一种是使用前后置事件,另一种则是使用ModelInspector。后者对DI提供了更好的支持。其中NH内嵌的ConventionModelMapper就是使用了后者,看它的构造函数
1: public class ConventionModelMapper : ModelMapper
2: {
3: public ConventionModelMapper()
4: : base(new SimpleModelInspector())
5: {
6: AppendDefaultEvents();
7: }
8: }
其实ModelMapper的构造函数有好几个重载,估计是能实现更强的自定义功能吧,我还没有尝试过。
 
然后,尝试集成进Spring.Net 1.3.2
Spring.Net这货,虽然提供了Spring.Data.NHibernate32.dll,但是其实是把基于NH2.x的代码在结合NH3.2重新build了一遍而已= =
好歹Spring提供了不错的扩展性,自己动手丰衣足食吧~~
1: public class Nh3LocalSessionFactoryObject : LocalSessionFactoryObject
2: {
3: public IEnumerable Mappings { get; set; }
4: public IModelInspector ModelInspector { get; set; }
5:
6: protected override void PostProcessMappings(Configuration config)
7: {
8: base.PostProcessMappings(config);
9:
10: var mapper = new ModelMapper(ModelInspector);
11: foreach (var mapping in Mappings)
12: {
13: mapper.AddMapping(mapping);
14: }
15: var hbmMappings = mapper.CompileMappingForEachExplicitlyAddedEntity();
16: foreach (var hbmMapping in hbmMappings)
17: {
18: config.AddMapping(hbmMapping);
19: }
20: }
21: }
其中,IConformistHoldersProvider是ClassMapping、SubClassMapping等几个Mapping类共同实现的接口。 ModelInspector的话,我会使用SimpleModelInspector,毕竟这篇文章就是想试试default convention。
 
那么,效果如何呢?
对比EF 4.1的话,有些不同也有些差距。
例如NH3.2默认表名=类名,而EF4.1则默认表名=类名的复数。
再例如EF 4.1中,如果用int做id则默认该id是自增长的,NH3.2中则还是要写代码,我将它写在基类里。
1: public class EntityClassMapping : ClassMapping
2: where TEntity : class, IEntity
3: {
4: public EntityClassMapping()
5: {
6: Id(e => e.Id, mapper => mapper.Generator(Generators.Identity));
7: Table(TableName);
8: }
9:
10: private string TableName
11: {
12: get { return typeof (TEntity).Name + "s"; }//todo
13: }
14: }
 
接下来,尝试一下覆盖default convention
例如,给一列重命名,代码如下
1: public class PersonMapping : EntityClassMapping
2: {
3: public PersonMapping()
4: {
5: Property(p => p.IsMale, mapping => mapping.Column("Gender"));
6: }
7: }
实话实说,我觉得这个API设计的是比较丑陋的。。。对比EF 4.1中实现相同任务的代码
1: public class PersonMapping : EntityMapping
2: {
3: public PersonMapping()
4: {
5: Property(p => p.IsMale).HasColumnName("Gender");
6: }
7: }
在整个NH3.2的mapping by code API中都充斥满了Action真是让人不胜其烦。
本文就到这里,说的实在是比较简略,不过我也一向没有写科普blog的兴致= =
更多细节还是请参考Fabio Maulo的blog。
Tags: 

延伸阅读

最新评论

发表评论