導航屬性是 FreeSql 的特色功能之一,可通過約定配置、或自定義配置對象間的關系。
導航屬性有 OneToMany, ManyToOne, ManyToMany, OneToOne, Parent 五種配置關系。
有了導航屬性,多表查詢會非常方便,lambda 表達式中直接使用導航對象點點點,舒服!!
- 可約定(命名約定),可不約定(需指定 Navigate 特性關聯);
- 無關聯的,查詢時可以指明 On 條件,LeftJoin(a => a.Parent.Id == a.ParentId);
- 已關聯的,直接使用導航對象就行,On 條件會自動附上;
除了查詢還有更多其他的特性在后續文章中再介紹。
自定義導航關系
//導航屬性,OneToMany
[Navigate(nameof(song_tag.song_id))]
public virtual List<song_tag> Obj_song_tag { get; set; }
//在 song_tag 查找 song_id 屬性,與 本實體.主鍵 關聯
//導航屬性,ManyToOne/OneToOne
[Navigate(nameof(song_id))]
public virtual Song Obj_song { get; set; }
//在 本實體 查找 song_id 屬性,與 Song.主鍵 關聯
//導航屬性,ManyToMany
[Navigate(ManyToMany = typeof(tag_song))]
public virtual List<tag> tags { get; set; }
也可以使用 FluentApi 在外部設置導航關系:
fsql.CodeFirst.ConfigEntity<實體類>(a => a
.Navigate(b => b.roles, null, typeof(多對多中間實體類))
.Navigate(b => b.users, "uid")
);
優先級,特性 > FluentApi
檢測導航屬性
如何檢測一個導航屬性是否配置生效:
var tbref = g.sqlite.CodeFirst
.GetTableByEntity(typeof(T))
.GetTableRef("Children", true);
GetTableRef(string propertyName, bool isThrow);
約定命名(無須指明 Navigate)
OneToOne 一對一
class User {
public int Id { get; set; } //Id、UserId、User_id
public UserExt UserExt { get; set; }
}
class UserExt {
public int id { get; set; } //Id、UserId、User_id、UserExtId、UserExt_id
public User User { get; set; }
}
ManyToOne 多對一
class Group {
public int Id { get; set; } //Id、GroupId、Group_id
}
class User {
public int Id { get; set; } //Id、UserId、User_id
public int AGroupId { get; set; }
public Group AGroup { get; set; }
public int BGroupId { get; set; }
public Group BGroup { get; set; }
}
OneToMany 一對多
class Group {
public int Id { get; set; } //Id、GroupId、Group_id
public ICollection<User> AUsers { get; set; }
public ICollection<User> BUsers { get; set; }
}
class User {
public int Id { get; set; } //Id、UserId、User_id
public int AGroupId { get; set; }
public Group AGroup { get; set; }
public int BGroupId { get; set; }
public Group BGroup { get; set; }
}
Parent 父子
class Group {
public int Id { get; set; } //Id、GroupId、Group_id
public int ParentId { get; set; } //ParentId、Parent_id
public Group Parent { get; set; }
public ICollection<Group> Childs { get; set; }
}
父子關系,與一對多其實差不多,添加數據參數上面的連接;
ManyToMany 多對多
class Song {
[Column(IsIdentity = true)]
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
class Song_tag {
public int Song_id { get; set; }
public virtual Song Song { get; set; }
public int Tag_id { get; set; }
public virtual Tag Tag { get; set; }
}
class Tag {
[Column(IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
public int? Parent_id { get; set; }
public virtual Tag Parent { get; set; }
public virtual ICollection<Song> Songs { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
Song、Tag、Song_tag,這三個實體使用了 OneToMany、ManyToOne、Parent、ManyToMany 4種關系。
系列文章導航
-
(十八)導航屬性