接下來三篇分享內容說明『規格快取』、『規格同步』、『資料初始化』。
下圖是啟動 Kuick 生命週期的 7 項事件中有關資料的部份,首先從『Schema Cache 規格快取』說起。
ORM 都應實作規格快取。
Kuick ORM 在 Kuick Application Lifecycle 資料庫啟動前 (PreDatabaseStart) 事件裡,完成規格快取,程式實作於 Kuick.Data.DataStart 類別的 DoPreDatabaseStart 方法。
foreach(Assembly assembly in Reflector.Assemblies) {
List<Type> types = Reflector.GatherByAttribute<EntitySpec>(assembly);
foreach(Type type in types) {
if(type.IsAbstract) { continue; }
IEntity one = Reflector.CreateInstance(type) as IEntity;
if(null == one) { continue; }
Table table = one.Table;
if(null == table.Spec) { continue; }
List<Column> columns = one.Columns;
EntityCache.Add(one);
il.Add("Entity Name", one.EntityName);
}
}
這段程式,從所有組件裡取出有在 class 定義 EntitySpec Attribute 的類別,產生實體並經由呼叫 Table 與 Columns 屬性,取得完整的資料規格後,再將其快取於 EntityCache 類別。
更細節的快取內容請查看 Kuick.Data.Entity 的 Table 與 Columns 屬性
<Entity Table property>
將資料表的『CategoryAttribute 分類』、『DescriptionAttribute 描述』、『EntitySpec 規格』、『EntityMapping 多對多參照』、『EntityIndex 索引』、『EntityVisual 分頁顯示設定』一併快取。
public Table Table
{
get
{
if(null == _Table) {
lock(_Lock) {
if(null == _Table) {
if(Heartbeat.Singleton.PreDatabaseStartFinished) {
IEntity instance = EntityCache.Get(EntityName);
if(null == instance) { throw new NullReferenceException(); }
_Table = instance.Table;
} else {
_Table = new Table();
object[] objs = this.GetType().GetCustomAttributes(true);
CategoryAttribute category = null;
DescriptionAttribute description = null;
EntitySpec spec = null;
List<EntityMapping> mappings = new List<EntityMapping>();
List<EntityIndex> indexes = new List<EntityIndex>();
EntityVisual visual = null;
foreach(object x in objs) {
if(x is CategoryAttribute) {
category = (CategoryAttribute)x;
continue;
}
if(x is DescriptionAttribute) {
description = (DescriptionAttribute)x;
continue;
}
if(x is EntitySpec) {
spec = (EntitySpec)x;
spec.Table = _Table;
continue;
}
if(x is EntityIndex) {
EntityIndex index = (EntityIndex)x;
index.Table = _Table;
indexes.Add(index);
continue;
}
if(x is EntityMapping) {
EntityMapping mapping = (EntityMapping)x;
mapping.Table = _Table;
mappings.Add(mapping);
continue;
}
if(x is EntityVisual) {
visual = (EntityVisual)x;
visual.Table = _Table;
continue;
}
}
// CategoryAttribute
if(null == category) {
category = new CategoryAttribute(
this.GetType().Namespace
);
}
// DescriptionAttribute
if(null == description) {
description = new DescriptionAttribute(
this.GetType().Name.TrimEnd(Constants.Entity.Suffix)
);
}
_Table.EntityName = EntityName;
_Table.TableName = TableName;
_Table.Class = this.GetType();
_Table.Category = category;
_Table.Description = description;
_Table.Spec = spec;
_Table.Indexes = indexes;
_Table.Mappings = mappings;
_Table.Visual = visual;
}
}
}
}
return _Table;
}
}
<Entity Columns property>
將資料欄位的『CategoryAttribute 分類』、『DescriptionAttribute 描述』、『ColumnSpec 規格』、『ColumnEncrypt 加解密』、『ColumnRefer 參照』、『ColumnInitiate 初始值』、『ColumnVisual 顯示設定』、『IValidation 資料檢驗條件』一併快取。
public List<Column> Columns
{
get
{
if(null == _Columns) {
lock(_Lock) {
if(null == _Columns) {
if(Heartbeat.Singleton.PreDatabaseStartFinished) {
IEntity instance = EntityCache.Get(EntityName);
if(null == instance) { throw new NullReferenceException(); }
_Columns = instance.Columns;
} else {
_Columns = new List<Column>();
foreach(PropertyInfo info in this.GetType().GetProperties()) {
Column column = new Column();
object[] objs = info.GetCustomAttributes(true);
CategoryAttribute category = null;
DescriptionAttribute description = null;
ColumnSpec spec = null;
ColumnEncrypt encryptor = null;
ColumnRefer refer = null;
ColumnInitiate initiate = null;
ColumnVisual visual = null;
List<IValidation> validations = new List<IValidation>();
foreach(object x in objs) {
if(x is CategoryAttribute) {
category = (CategoryAttribute)x;
continue;
}
if(x is DescriptionAttribute) {
description = (DescriptionAttribute)x;
continue;
}
if(x is ColumnSpec) {
spec = (ColumnSpec)x;
spec.Column = column;
continue;
}
if(x is ColumnEncrypt) {
encryptor = (ColumnEncrypt)x;
encryptor.Column = column;
continue;
}
if(x is ColumnRefer) {
refer = (ColumnRefer)x;
refer.Column = column;
if(refer.Style == ReferValue.Self) {
refer.Type = this.GetType();
}
continue;
}
if(x is ColumnInitiate) {
initiate = (ColumnInitiate)x;
initiate.Column = column;
continue;
}
if(x is ColumnVisual) {
visual = (ColumnVisual)x;
visual.Column = column;
continue;
}
if(x is IValidation) {
IValidation validation = (IValidation)x;
Reflector.SetValue(validation, "Column", column);
validations.Add(validation);
continue;
}
}
// ColumnSpec
if(null == spec) {
continue;
} else {
if(Checker.IsNull(spec.ColumnName)) {
spec.ColumnName = SqlNamingConvention
.ToColumnName(this.GetType(), info);
}
}
// CategoryAttribute
if(null == category) {
category = new CategoryAttribute(
Constants.Default.Category
);
}
// DescriptionAttribute
if(null == description) {
description = new DescriptionAttribute(
Formator.DividePascalCasing(info.PropertyType.Name)
);
}
// ColumnRefer
if(null == refer) {
refer = new ColumnRefer(ReferValue.None);
}
// ColumnInitiate
if(null == initiate) {
initiate = new ColumnInitiate(InitiateValue.None);
}
// ColumnVisual
if(null == visual) {
visual = new ColumnVisual();
}
column.TableName = TableName;
column.EntityName = EntityName;
column.Category = category;
column.Description = description;
column.Property = info;
column.Spec = spec;
column.Refer = refer;
column.Initiate = initiate;
column.Visual = visual;
column.Encryption = encryptor;
column.Validations = validations;
column.Foolproof();
if(
Current.Data.Concurrency
||
column.Spec.ColumnName != VERSION_NUMBER) {
_Columns.Add(column);
}
}
}
}
}
}
return _Columns;
}
}
========================================
鐵人賽分享列表:Kuick Application & ORM Framework
開放原始碼專案:kuick.codeplex.com
直接下載原始碼:Kuick
下載相關文件檔:C# Code Conventions and Design Guideline
相關教學影片區:Kuick on YouTube
請問一下,我想將kuick中對db Schema 處理的部分,應用到SQL SSIS 2005中
,從下載來的檔案並沒有提到的那些dll檔,有source code,是指自行編譯為dll檔嗎?
這方面有點陌生,故此詢問一下,編譯出來的檔案有x86 或 x64的系統限制嗎?
另外如何這不適合發問,在煩請砍文,謝謝!
迎歡 abcg5 的發問,如果只需要 dll,可以參考『Kuick -- 使用 NuGet 建立 ORM 專案』這篇分享說明,或是下載原始檔進行編譯,目前的專案編譯設定皆為 Any CPU,這也可以自行調整後再編譯。
近日會有更新一版,會額外將 dll 單獨提供下載。
您也可以直接發 email 給我 kevinjong@gmail.com