階層式資料結構,常用來設計『分類』、『組織部門』等資料,請參考下面 2 篇資料模型解說階層式資料結構,同時,HierarchyEntity 由此分別定義出如下欄位:
1. Hierarchical database model 階層式資料模型
HierarchyEntity 定義出 ParentID (上層代碼) 欄位
2. Nested set model 巢狀式模型
HierarchyEntity 定義出 Left, Right (左右循序表示數值) 欄位
本篇說明,請同時參照原始檔:
命名空間:Kuick.Data.HierarchyEntity
檔案路徑:Kuick v1.0.0.0\Kuick.Data\Entity\HierarchyEntity.cs
什麼是階層式資料結構?所有有自我參照需求的資料結構稱之為階層式資料結構。Kuick Entity 內建 HierarchyEntity 已經實作階層式資料該有的資料欄位定義,與其他配套的處理內容,詳述如下:
<資料欄位>
1. ParentID 上層代碼
欄位值邏輯上參照自己的 PK 欄位。
[ColumnSpec(256)]
[ColumnRefer(ReferValue.Self)]
public string ParentID { get; set; }
2. Left 左循序數值
定義為系統欄位
[ColumnSpec]
[ColumnVisual(VisualFlag.SystemColumn)]
public int Left { get; set; }
3. Right 右循序數值
定義為系統欄位
[ColumnSpec]
[ColumnVisual(VisualFlag.SystemColumn)]
public int Right { get; set; }
<階層式資料相關屬性>
IsRoot 是否為根部
Level 階層深度層級
HasChild 是否存在下層資料
HasNext 是否存在同層下一筆資料
Path 由本身至根部的階層代碼矩陣
Parent 上層物件
Next 同層下一筆資料物件
Previous 同層上一筆資料物件
Siblings 同層資料物件矩陣
Children 所有下一層資料物件矩陣
Descendant 所有下層資料物件矩陣
public bool IsRoot
{
get
{
return string.IsNullOrEmpty(ParentID);
}
}
public int Level
{
get
{
return Parents.Count;
}
}
public bool HasChild
{
get
{
return Children.Count > 0;
}
}
public bool HasNext
{
get
{
bool find = false;
foreach(T one in Siblings) {
if(find) { return true; }
if(one.KeyValue == KeyValue) { find = true; }
}
return false;
}
}
public List<string> Path
{
get
{
List<string> list = new List<string>();
foreach(T one in Parents) {
list.Add(one.KeyValue);
}
return list;
}
}
public T Parent
{
get
{
if(Checker.IsNull(_Parent)) {
if(ParentID != KeyValue) {
_Parent = Nodes.Find(delegate(T x) {
return x.KeyValue == ParentID;
});
}
}
return _Parent;
}
}
public T Next
{
get
{
if(null == _Next) {
bool find = false;
foreach(T one in Siblings) {
if(find) {
_Next = one;
break;
}
if(one.KeyValue == KeyValue) { find = true; }
}
}
return _Next;
}
}
public T Previous
{
get
{
if(null == _Previous) {
bool find = false;
T previous = null;
foreach(T one in Siblings) {
if(one.KeyValue == KeyValue) { find = true; break; }
previous = one;
}
_Previous = find ? previous : null;
}
return _Previous;
}
}
public List<T> Siblings
{
get
{
if(null == _Siblings) {
lock(_Lock) {
if(null == _Siblings) {
_Siblings = Nodes.FindAll(delegate(T x) {
return x.ParentID == ParentID;
});
}
}
}
return _Siblings;
}
}
public List<T> Children
{
get
{
if(null == _Children) {
lock(_Lock) {
if(null == _Children) {
_Children = Nodes.FindAll(delegate(T x) {
return x.ParentID == KeyValue;
});
}
}
}
return _Children;
}
}
public List<T> Descendant
{
get
{
if(Checker.IsNull(_Descendant)) {
List<T> list = new List<T>();
List<T> children = Children;
while(!Checker.IsNull(children)) {
children = null;
foreach(T one in children) {
if(!list.Contains(one)) {
one.Nodes = Nodes;
list.Add(one);
children.AddRange(one.Children);
}
}
}
_Descendant = list;
}
return _Descendant;
}
}
<啟用資料一致性功能>
一致性功能的啟用設定,請參閱前一篇文章『Kuick Entity:Entity 基本資料結構』說明。
public override Flag Concurrency
{
get
{
return Kuick.Flag.Enable;
}
}
<預設資料篩選>
資料篩選條件設定,請參閱前一篇文章『Kuick Entity:Entity 基本資料結構』說明。
階層式資料,預設依據 Left 欄位值排序。
public override void Interceptor(Sql sql)
{
sql.OrderBy(new SqlOrderBy(LEFT));
base.Interceptor(sql);
}
========================================
鐵人賽分享列表:Kuick Application & ORM Framework
開放原始碼專案:kuick.codeplex.com
直接下載原始碼:Kuick
下載相關文件檔:C# Code Conventions and Design Guideline
相關教學影片區:Kuick on YouTube