NBearV3——ORM实体关系设计速查手册
四、1对多关联
分析:一对多关联指一个实体通过被关联实体的一个外键关联多个被关联实体的集合。举例来说,下面的图表示Team可以包含多个User的关联。 
public interface Team : Entity { [PrimaryKey] Guid ID { get; set; } string Name { get; set; } [FkQuery("Team", OrderBy="{Name} DESC", Contained=true, LazyLoad=true)] User[] Users { get; set; } } public interface User : Entity { [PrimaryKey] Guid ID { get; set; } string Name { get; set; } [FkReverseQuery(LazyLoad=true)] Team Team { get; set;} }
注1:FkQuery的OrderBy属性,可以指定一个类似SQL语法的排序规则,用于对一组关联的对象进行排序。本手册中的其他OrderBy属性的含义总是和这里的含义相同。
注2:FkQuery的构造函数的第一个参数(如Team.Users属性中OneToManyQuery构造函数的第一个参数Team)指定对应的被关联实体中的关联属性。这个关联属性可以是一个FkReverseQuery属性(即双向引用),也可以是一个外键属性(即只在One实体包含到Many实体的引用)。本例中演示的是双向引用,如果只想包含单向引用的话,可以将User.Team属性改为一个简单的外键属性,并将OneToManyQuery构造函数的第一个参数Team修改为这个外键属性的名称,示例代码如下:
public interface Team : Entity { [PrimaryKey] Guid ID { get; set; } string Name { get; set; } [FkQuery("TeamID", Contained=true, LazyLoad=true)] User[] Users { get; set; } } public interface User : Entity { [PrimaryKey] Guid ID { get; set; } string Name { get; set; } [FriendKey(typeof(Team))] Guid TeamID { get; set; } }
注3:FkQuery允许设置一个Contained属性,使得被关联对象元素随主对象更新时自动级联更新。本手册中其他Attribute的Contained属性的含义,总是和这里的Contained的含义相同。
五、1对多自关联
分析:1对多自关联和普通的1对多关联的定义方法完全相同。 
public interface Group : Entity { [PrimaryKey] Guid ID { get; set; } string Name { get; set; } [FkReverseQuery(LazyLoad=true)] [MappingName("ParentID")] Group ParentGroup { get; set; } [FkQuery("ParentGroup", LazyLoad=true)] [SerializationIgnore] Group[] ChildGroups { get; set; } }
注:一对多自关联时,同样必须注意至少设置其中一个引用为LazyLoad=true,且至少设置其中一个引用为SerializationIgnore,以避免序列化时的死循环。
六、多对多关联
分析:多对多关联指一个实体可以关联另一个实体的多个对象,而这个被关联实体,也可以关联到这个实体的多个对象。以下面的Group和User的关联为例,Group中可以有多个User,User也可以在多个Group中。在映射多对多关联的的实体到数据库表时,我们总是需要有一个独立的关联表,对应这里的UserGroup关联实体。 
public interface Group : Entity { [PrimaryKey] Guid ID { get; set; } string Name { get; set; } [ManyToManyQuery(typeof(UserGroup), LazyLoad=true)] User[] Users { get; set; } } public interface User : Entity { [PrimaryKey] Guid ID { get; set; } string Name { get; set; } [ManyToManyQuery(typeof(UserGroup), LazyLoad = true)] Group[] Groups { get; set;} } [Relation] public interface UserGroup : Entity { [RelationKey(typeof(User))] Guid UserID { get; set; } [RelationKey(typeof(Group))] Guid GroupID { get; set; } }
注1:用于多对多关联的关联实体必须使用RelationAttribute标识。它的用于关联多和多双方的属性,必须用RelationKeyAttribute标识,RelationKeyAttribute的唯一一个构造函数参数,如这个里的typeof(User)和typeof(Group)分别表示,这两个属性用于关联到这两个实体。
注2:在实体Group和User中,我们必须为属性Users和Groups设置ManyToManyQueryAttribute,并且用关联实体UserGroup的类型值作为ManyToManyQuery的唯一的构造函数参数。