NHibernate3剖析:Mapping篇之ConfORM實戰(3):OneToOne語義
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工具測試,你可以看見下面輸出:
對于單向一對一關聯,實際就是設置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
測試生成字符串:
對于雙向一對一關聯,實際就是設置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
測試生成字符串:
類似的,匹配到以下模式適配器:
BidirectionalForeignKeyAssociationManyToOneApplier:應用IManyToOneMapper.Unique(true)和IManyToOneMapper.Cascade(Cascade.All)
BidirectionalForeignKeyAssociationOneToOneApplier:應用IOneToOneMapper.PropertyReference(GetPropertyOf(manyToOneSideType, oneToOneSideType))
BidirectionalPrimaryKeyAssociationMasterOneToOneApplier:應用IOneToOneMapper..Cascade(Cascade.All)
結語
這篇文章展示ConfORM的One-to-One語義應用,映射了三種One-to-One映射。
參考資料
Fabio Maulo:ConfORM:“Mapping” One-To-One