兩個資料表如果存在多對多的關連,勢必需要有第三個資料表(關連資料表)記載這項關係,最簡單的關連資料表只需2個欄位,分別存放所關連到資料表的主鍵欄位值。這樣的需求條件下,Kuick提供一個內鍵的功能(多對多關連服務, Kuick.BuiltIn.Mapping),提供建立任意兩個資料表之間的關連,甚至是資料表自我關連亦可。
請下載今天的範例程式碼 Labs-2013-10-04
1. 「多對多關連服務」資料結構
多對多關連服務需要記錄任意兩個Entity的任意兩筆資料的關連,先從下圖的資料結構來看。
T_MAPPING資料表依據兩個Entity的Class名稱,區分成PRE_ORDER(前序)與POST_ORDER(後序),分別記錄Entity名稱、鍵值與序次
例如:以EmployeeEntity與RoleEntity為例,EmployeeEntity其中一筆資料鍵值為kevin,RoleEntity其中一筆資料鍵值為manager。
前序 -- EmployeeEntity
後序 -- RoleEntity
如果kevin與manager如果建立關連,T_MAPPING資料表將增加一筆資料
2.「多對多關連服務」介面定義
「多對多關連服務」介面定義在Kuick.Data組件裡,實作於Kuick.Builtin.Mapping組件。
int Count<TContainer, TMember>(string containerID)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
bool Exists<TContainer, TMember>(string containerID, string memberID)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
Result Add<TContainer, TMember>(string containerID, params string[] memberIDs)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
Result Remove<TContainer, TMember>(string containerID, params string[] memberIDs)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
Result Clear<TContainer, TMember>(string containerID)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
void Sorting<TContainer>(params string[] ids)
where TContainer : class, IEntity, new();
void Sorting<TContainer, TMember>(string containerID, params string[] memberIDs)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
List<TMember> Get<TContainer, TMember>(params string[] containerIDs)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
List<TMember> Get<TContainer, TMember>(
Func<Sql<TMember>, Sql<TMember>> sqlIntercepter,
params string[] containerIDs)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
List<string> AllMemberIDs<TContainer, TMember>(string containerID)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
Sql<TMember> GetSql<TContainer, TMember>(params string[] containerIDs)
where TContainer : class, IEntity, new()
where TMember : class, IEntity, new();
int Count(
string containerEntityName,
string memberEntityName,
string containerID);
bool Exists(
string containerEntityName,
string memberEntityName,
string containerID,
string memberID);
Result Add(
string containerEntityName,
string memberEntityName,
string containerID,
params string[] memberIDs);
Result Remove(
string containerEntityName,
string memberEntityName,
string containerID,
params string[] memberIDs);
Result Clear(
string containerEntityName,
string memberEntityName,
string containerID);
void Sorting(
string containerEntityName,
params string[] ids);
void Sorting(
string containerEntityName,
string memberEntityName,
string containerID,
params string[] memberIDs);
List<IEntity> Get(
string containerEntityName,
string memberEntityName,
params string[] containerIDs);
List<IEntity> Get(
string containerEntityName,
string memberEntityName,
Func<Sql, Sql> sqlIntercepter,
params string[] containerIDs);
List<string> AllMemberIDs(
string containerEntityName,
string memberEntityName,
string containerID);
3. 在EmployeeEntity與RoleEntity裡,增加對應關連
EmployeeEntity裡,增加所屬角色集合
private List<RoleEntity> _Roles;
public List<RoleEntity> Roles
{
get
{
if(null == _Roles) {
_Roles = Mapping<RoleEntity>().Get();
}
return _Roles;
}
}
RoleEntity裡,增加成員集合
private List<EmployeeEntity> _Employees;
public List<EmployeeEntity> Employees
{
get
{
if(null == _Employees) {
_Employees = Mapping<EmployeeEntity>().Get();
}
return _Employees;
}
}