系列引入
NHibernate3剖析系列分别从Configuration篇、Mapping篇、Session篇、Core篇、Tool篇、Practice篇、Extension篇等方面全面揭示NHibernate3版本内容、特性及其应用,完全基于NHibernte3版本。
- NHibernate专题:http://kb.cnblogs.com/zt/nhibernate/
- NHibernate官方站点:http://nhforge.org/
- NHibernate参考文档:http://nhforge.org/doc/nh/en/
- 获取NHibernate地址:http://sourceforge.net/projects/nhibernate/files/
ConfORM概述
在ConfORM实战(1):概览中,描述了ConfORM简单使用。在ConfORM实战(2):原理中介绍了ConfORM的基本实现原理。如果你不熟悉ConfORM请查看前几篇文章,你也可以到http://code.google.com/p/codeconform/获取ConfORM。
在这之前,我们需要为HbmMapping写AsString()扩展方法:用于输出HbmMapping对象的Mapping,用于学习测试使用,具体代码参考这里。
在Domain设计中,关联关系有单向关联和双向关联两种,那么一对一我们可以分为单向一对一关联(Unidirectional one-to-one)、双向一对一主键关联(Bidirectional one-to-one (primary key association))、双向一对一外键关联(Bidirectional one-to-one (foreign key association))三种情况。这篇使用ConfORM“映射”这些Domain实例吧。
One-to-One语义
我们使用ObjectRelationalMapper类中的OneToOne方法定义两个对象一对一关系。
单向一对一关联(Unidirectional one-to-one)
1.Domain
设计单向一对一关联Domain实例,Person对象和Address对象,人有一个地址。
public class Person { public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } } public class Address { public int Id { get; set; } public string Street { get; set; } public int CivicNumber { get; set; } }
2.ConfORM
使用ConfORM来配置Domain,使之编译生成我们需要的HbmMapping对象。(注意黑体)
[Test] public void UnidirectionalOneToOneMappingDemo() { //show how work with one-to-one and how ConfORM understands OOP var orm = new ObjectRelationalMapper(); var mapper = new Mapper(orm); var entities = new[] { typeof(Person), typeof(Address) }; //use the definition of table-to-class strategy class by class orm.TablePerClass(entities); // Defining relations orm.OneToOne<Person, Address>(); // Show the mapping to the console var mapping = mapper.CompileMappingFor(entities); Console.Write(mapping.AsString()); }
3.Mapping
上面测试输出HbmMapping的映射字符串,如果你使用ReSharper或者TestDriven.Net工具测试,你可以看见下面输出:
4.原理
对于单向一对一关联,实际就是设置IManyToOneMapper,ConfORM会在IPatternsAppliersHolder的ManyToOne和ManyToOnePath集合中匹配对应模式适配器,即匹配UnidirectionalOneToOneUniqueCascadeApplier模式适配器,进行相应操作。
UnidirectionalOneToOneUniqueCascadeApplier:应用IManyToOneMapper.Unique(true)和ManyToOneMapper.Cascade(applyCascade.HasValue?applyCascade.Value : Cascade.All)。
双向一对一主键关联(Bidirectional one-to-one (primary key association))
1.Domain
设计双向一对一关联Domain实例,Person对象和Address对象,人有一个地址,地址有一个人。
public class Person { public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } } public class Address { public int Id { get; set; } public Person Person { get; set; } public string Street { get; set; } public int CivicNumber { get; set; } }
2.ConfORM
使用ConfORM来配置Domain,使之编译生成我们需要的HbmMapping对象。其实这个代码和上面的一样:
[Test] public void BidirectionalOneToOneMappingDemo1() { //show how work with one-to-one and how ConfORM understands OOP var orm = new ObjectRelationalMapper(); var mapper = new Mapper(orm); var entities = new[] { typeof(Person), typeof(Address) }; //use the definition of table-to-class strategy class by class orm.TablePerClass(entities); // Defining relations orm.OneToOne<Person, Address>(); //or orm.OneToOne<Address,Person>(); // Show the mapping to the console var mapping = mapper.CompileMappingFor(entities); Console.Write(mapping.AsString()); }
3.Mapping
测试生成字符串:
4.原理
对于双向一对一关联,实际就是设置IOneToOneMapper,ConfORM会在IPatternsAppliersHolder的OneToOne和OneToOnePath集合中匹配对应模式适配器,即匹配到以下三个模式适配器,进行相应操作。
BidirectionalPrimaryKeyAssociationMasterOneToOneApplier:应用IOneToOneMapper.Cascade(Cascade.All)
BidirectionalOneToOneAssociationPoidApplier:应用IIdMapper.Generator(Generators.Foreign(BidirectionalOneToOneOrNull(subject.ReflectedType)))
BidirectionalPrimaryKeyAssociationSlaveOneToOneApplier:应用IOneToOneMapper.Constrained(true)
双向一对一外键关联(Bidirectional one-to-one (foreign key association))
Domain与双向一对一主键关联(Bidirectional one-to-one (primary key association))相同。
2.ConfORM
配置Domain,注意黑体
[Test] public void BidirectionalOneToOneMappingDemo2() { //show how work with one-to-one and how ConfORM understands OOP var orm = new ObjectRelationalMapper(); var mapper = new Mapper(orm); var entities = new[] { typeof(Person), typeof(Address) }; //use the definition of table-to-class strategy class by class orm.TablePerClass(entities); // Defining relations orm.ManyToOne<Person, Address>(); orm.OneToOne<Address, Person>(); // Show the mapping to the console var mapping = mapper.CompileMappingFor(entities); Console.Write(mapping.AsString()); }
3.Mapping
测试生成字符串:
4.原理
类似的,匹配到以下模式适配器:
BidirectionalForeignKeyAssociationManyToOneApplier:应用IManyToOneMapper.Unique(true)和IManyToOneMapper.Cascade(Cascade.All)
BidirectionalForeignKeyAssociationOneToOneApplier:应用IOneToOneMapper.PropertyReference(GetPropertyOf(manyToOneSideType, oneToOneSideType))
BidirectionalPrimaryKeyAssociationMasterOneToOneApplier:应用IOneToOneMapper..Cascade(Cascade.All)
版权声明:本文为博主http://www.zuiniusn.com 原创文章,未经博主允许不得转载。