NBearV3——ORM实体关系设计速查手册


?本手册演示NBearV3支持的所有实体关系设计的完全参考。包括1对1,1对多,多对多关联以及自关联的正向、反向引用时的所有情况的设计方法。

?

??? 注1:本手册并不讨论继承关系。因为,继承关系自然映射到设计实体接口的继承,无需太多额外讨论。

??? 注2:所有的关联在演示中都包含了正向和反向的可读写引用,在实际的项目中,一般并不总是需要同时有正向和反向引用,可以只在一个方向包含引用,或一方包含引用,另一方只包含一个外键ID,也可以只包含只读的引用。并且,在双向引用时,绝对不能同时设置为双向的LazyLoad=false。

??? 注3:所有关联关系中的正向或反向引用的属性,根据需要,可以添加ContainedAttribute标识,以实现属性和包含属性的实体的级联更新/删除。在本文演示的所有引用中都没有包含ContainedAttribute,实际项目中请注意添加,但是不要同时在正向和反向引用属性中添加ContainedAttribute。

??? 注4:在阅读本文之前,建议读者先阅读《NBearV3 Step by Step教程——ORM篇》以掌握NBearV3中有关ORM的基本知识。

??? 本手册演示的所有类图和代码,包含于可以从sf.net下载的NBearV3最新源码zip包中的tutorials\ Entity_Relation_Manual目录中。因此,在使用本手册的过程中如有任何疑问,可以直接参考这些代码。

??? 一、1对1主键关联

?

?? 分析:一对一主键关联指的是两个实体通过相同的主键进行关联。典型的关联关系如图中的User和UserProfile的关联。其中,UserProfile不能脱离具有相同主键值的User存在。因此,实际上,对于UserProfile来说,它的属性UserID既是它的PK,又是一个关联到User的FK,且UserProfile.UserID应该对User.ID有引用完整性约束。

public interface User : Entity
{
[PrimaryKey]
Guid ID { get; set; }
string Name { get; set; }
[PkQuery(LazyLoad=true)]
UserProfile Profile
{
get;
set;
}
}
public interface UserProfile : Entity
{
[PrimaryKey]
[FriendKey(typeof(User))]
Guid UserID { get; set; }
string Content { get; set; }
[PkReverseQuery(LazyLoad = true)]
User User
{
get;
set;
}
}

??? 二、1对1外键关联


? 分析:一对一外键关联指的是一个实体通过自己的一个外键和另一个实体进行关联。一对一外键关联无论在关联语义还是数据库映射上都和1对多(外键)关联非常类似,所以,对于1对多(外键)关联中FkQuery和FkReverseQuery的解释同样适用于1对1外键关联的情形。典型的关联关系如图中的User和UserProfile的关联。这里和前面的1对1主键关联的不同在于:此时,UserProfile.ID和User.ID并不相关,分别只作为各自实体的主键,UserProfile.UserID是一个外键,UserProfile通过这个外键关联到User实体。UserProfile.UserID应该对User.ID有引用完整性约束。

public interface User : Entity
{
[PrimaryKey]
Guid ID { get; set; }
string Name { get; set; }
[FkQuery("User", LazyLoad=true)]
UserProfile Profile
{
get;
set;
}
}
public interface UserProfile : Entity
{
[PrimaryKey]
Guid ID { get; set; }
string Content { get; set; }
[FkReverseQuery(LazyLoad=true)]
User User
{
get;
set;
}
}

??? 注:标识在User的Profile属性上的FkQuery的构造函数需要一个输入参数,该参数指定该外键查询引用属性对应的反向引用属性是UserProfile实体的User属性。

??? 三、1对1自关联

?? 分析:1对1自关联类似1对1外键关联,区别仅仅在于,关联的双方是同一个实体。

public interface Person : Entity
{
[PrimaryKey]
Guid ID { get; set; }
string Name { get; set; }
[FkReverseQuery(LazyLoad=true)]
[MappingName("MateID")]
[SerializationIgnore]
Person Mate { get; set; }
}

??? 注1:一对一自关联可以只使用一个属性表示双向的引用,也可以使用正反两个属性。但是,必须注意至少设置其中一个引用为LazyLoad=true,且至少设置其中一个引用为SerializationIgnore,以避免序列化时的死循环。

??? 注2:注意Person.Mate中的MappingName(“MateID”)。该Attribute是可选的。这里显式指定为MateID,表示Person实体映射到数据库表时,需要创建的用于关联Mate属性的字段名称为MateID。如果不指定,则默认值一般为”属性名_主键名”,以这里为例,如果不指定这个MappingName,则这个字段的名称为Mate_ID,因为属性名为Mate,关联类型Person的主键字段名为ID。本手册中其他为关联属性指定的MappingName的含义都同该注解。

本文作者:
« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3