淺談Orm框架XCode v3.5源碼發(fā)布
淺談Orm框架XCode v3.5源碼發(fā)布是本文要介紹的內(nèi)容,這段時間從我們各個系統(tǒng)抽取了基礎(chǔ)的常用的部分,整理后形成了一個XCode示例項目,包含三部分:DLL引用程序集、Web網(wǎng)站、YWS實體類庫。
之前發(fā)布了一些介紹XCode的文章,有些朋友希望能得到源碼,更多的朋友是想知道怎么用,想試一試!我們現(xiàn)有的系統(tǒng)是一個大體系,分割開來無法獨立工作,所以一直沒有提供XCode的例子項目?,F(xiàn)在整理的這個例子項目,用到了XCode中常用的70%功能,蘊含著XCode開發(fā)模式的思想,希望能加深大家對XCode的了解。
XCode v3.5源碼(及相關(guān)組件、例子、代碼生成器等)目前存放于CodePlex,地址:http://xcode.codeplex.com/
充血模型,我們把它做得極其的大,所以才有了很多看似不可能的功能,我們不知道對與錯,至少這么多年都走過來了(本文后面附上XCode開發(fā)日志,見證了XCode的風(fēng)風(fēng)雨雨)。
其中的泛型基類,很多朋友看起來都覺得很暈
- /// <summary>
- /// 管理員
- /// </summary>
- /// <typeparam name="TEntity">管理員實體類</typeparam>
- /// <typeparam name="TRoleEntity">角色實體類</typeparam>
- /// <typeparam name="TMenuEntity">菜單實體類</typeparam>
- /// <typeparam name="TRoleMenuEntity">角色菜單實體類</typeparam>
- /// <typeparam name="TLogEntity">日志實體類</typeparam>
- public partial class Administrator<TEntity, TRoleEntity, TMenuEntity, TRoleMenuEntity, TLogEntity> : Administrator<TEntity>
- where TEntity : Administrator<TEntity, TRoleEntity, TMenuEntity, TRoleMenuEntity, TLogEntity>, new()
- where TRoleEntity : Role<TRoleEntity, TMenuEntity, TRoleMenuEntity>, new()
- where TMenuEntity : Menu<TMenuEntity>, new()
- where TRoleMenuEntity : RoleMenu<TRoleMenuEntity>, new()
- where TLogEntity : Log<TLogEntity>, new()
- {
這個泛型類帶有五個泛型參數(shù),而每一個泛型參數(shù)都有相應(yīng)的約束,所繼承的基類本身也是泛型類。這種泛型的設(shè)計方式,讓我們能夠抽象大量公共操作。當(dāng)然,面向?qū)ο笾械某橄蠛吞摂M也可以抽象,但是我們這里通過泛型基類,還可以抽象靜態(tài)方法的實現(xiàn),這也是我們大量使用泛型基類的原因。
有時候為了方便,會用一點匿名函數(shù),如果匿名函數(shù)里面再用匿名函數(shù),就會讓人發(fā)瘋,如果匿名函數(shù)再跟泛型混起來使用,那是……
- /// <summary>
- /// 擁有權(quán)限的菜單
- /// </summary>
- [XmlIgnore]
- public virtual EntityList<TMenuEntity> MenuList
- {
- get
- {
- return GetExtend<TMenuEntity, EntityList<TMenuEntity>>("MenuList", delegate
- {
- EntityList<TMenuEntity> list = EntityList<TMenuEntity>.From<TRoleMenuEntity>(Menus, delegate(TRoleMenuEntity item)
- {
- return Menu<TMenuEntity>.FindByID(item.MenuID);
- });
- if (list != null) list.Sort(Menu<TMenuEntity>._.Sort, true);
- return list;
- });
- }
- set { Extends["MenuList"] = value; }
- }
以上舉了XCode開發(fā)模式中兩個很特別的地方。(這年頭,我們追求各家之長,大家都有的就不拿出來現(xiàn)啦?。?/p>
下面我們看看這個例子項目都有哪些亮點
1、自動創(chuàng)建數(shù)據(jù)庫、數(shù)據(jù)表,這是XCode自身支持的功能。XCode有一個設(shè)置DatabaseSchema_Enable,打開后,每次啟動網(wǎng)站,都將檢查表結(jié)構(gòu),如果數(shù)據(jù)庫或者數(shù)據(jù)表不存在,將會根據(jù)實體類信息自動創(chuàng)建,如果數(shù)據(jù)表結(jié)構(gòu)不一致,將會自動修改。目前支持Access、SQLite和MSSQL,其中MSSQL支持最完善,其它Oracle和MySQL等,隨著版本升級,很久沒有測試過。
而創(chuàng)建什么數(shù)據(jù)庫,Access、SQLite還是MSSQL,由連接字符串覺得,XCode所要做的第一個工作就是檢查現(xiàn)在的連接字符串對應(yīng)著哪一種數(shù)據(jù)庫,以及版本(MSSQL中很重要)。在這里,XCode的任務(wù)就是構(gòu)造一個適合系統(tǒng)工作的數(shù)據(jù)庫環(huán)境!
2、自動初始化數(shù)據(jù)。該功能由通用實體類組件CommonEntity實現(xiàn)。比如管理員實體類,在實體類的靜態(tài)構(gòu)造函數(shù)中,檢查管理員表的數(shù)據(jù),如果數(shù)據(jù)行數(shù)為0,表明沒有任何數(shù)據(jù),這個時候,代碼將創(chuàng)建一個用戶名和密碼都是admin的默認管理員,并寫入數(shù)據(jù)表。其它的還有角色、菜單、權(quán)限等初始化。配合上面第一個功能,這種設(shè)計讓系統(tǒng)的部署變得非常簡單。只要配置好連接字符串,告訴系統(tǒng)你要用什么數(shù)據(jù)庫,系統(tǒng)將會為你完成一切數(shù)據(jù)庫部署工作。
看看初始化之后的系統(tǒng)
3、樹形實體。菜單和權(quán)限頁面的樹形結(jié)構(gòu),有幾個特點:沒有使用路徑字段,只有簡單的ParentID字段;菜單互相嵌套不會死循環(huán),使用棧代替遞歸構(gòu)造菜單樹;不會大量讀取數(shù)據(jù)庫,因為有實體緩存,不僅緩存了每一個實體,還緩存了整顆樹。頁面上沒有太多的實現(xiàn)代碼,甚至在通用實體類組件里面的菜單基類,也沒有太多的代碼,因為菜單基類也是繼承自樹形實體基類EntityTree,后面的客戶類別屬于樹形實體,也是繼承自它。
4、模版生成。很多頁面都是在模版生成的基礎(chǔ)上稍作修改,風(fēng)格統(tǒng)一。
XCode例子項目會持續(xù)更新,可以從QQ群(10193406)的SVN上拿到最新的源碼,我們也會定期發(fā)布到CodePlex上!
XCode v3.5源碼(及相關(guān)組件、例子、代碼生成器等)目前存放于CodePlex,地址:http://xcode.codeplex.com/
附(XCode版本日志):
- /*
- * XCode的重大改進
- *
- * v6.0 增強的緩存和擴展屬性支持
- * v5.0 弱類型支持
- * v4.0 實體集合和緩存
- * v3.0 增加ORM的各種細節(jié)支持
- * v2.0 數(shù)據(jù)架構(gòu)功能,實體和數(shù)據(jù)結(jié)構(gòu)雙向映射
- * v1.2 使用泛型基類
- * v1.0 創(chuàng)建XCode
- * /
- /*
- * v6.5.2010.1223 修正SQLite已知的一些問題,查找dll文件路徑不正確,執(zhí)行插入語句不正確
- * IEntity增加CopyFrom方法,用于從指定實體對象復(fù)制成員數(shù)據(jù)
- * 增加對二進制字段的支持,表現(xiàn)為Byte[]
- *
- * v6.4.2010.1217 修正Entity中CheckColumn無法正確計算選擇字段的錯誤
- * 優(yōu)化SelectBuilder,允許Where中使用GroupBy字句,ToString時自動分割到正確位置
- * 實體類增加靜態(tài)方法FindByKeyForEdit,用于替代模版生成中的FindByKeyForEdit,為將要實現(xiàn)的表單基類(自定義表單)做準(zhǔn)備
- * ********************************
- * 實體基類繼承自BinaryAccessor,IEntity增加IIndexAccessor接口和IBinaryAccessor接口,增加對快速索引訪問和二進制訪問的支持
- * 快速索引訪問:實體類可以不必生成索引器代碼,IIndexAccessor直接提供按名稱訪問屬性
- * 二進制訪問:支持把實體對象序列化成二進制或者反向操作
- * 這兩個功能尚未經(jīng)過嚴格測試,請不要用于正式系統(tǒng)使用!
- *
- * v6.3.2010.1209 修正實體工廠EntityFactory緩存實體導(dǎo)致無法識別后加載實體程序集的錯誤
- *
- * v6.2.2010.1202 SQLite增加讀寫鎖,限制同時只能指定一個Excute操作
- * Entity的PageSplitSQL方法修正表名沒有進行格式化的BUG
- *
- * v6.1.2010.1119 取消依賴XLog,升級為依賴NewLife.Core,部分公共類庫移植到NewLife.Core
- * 修正EntityTree中FindChilds錯誤,增加排序字段的支持,如果指定排序字段,查詢子級的時候講按排序字段降序排序
- * 取消授權(quán)限制,但仍然混淆代碼
- *
- * v6.0.2010.1021 增加字典緩存DictionaryCache
- * 增加弱引用泛型WeakReference<T>
- * 單對象實體緩存改為弱引用,使得緩存對象在沒有引用時得到回收
- * 單對象實體緩存默認填充方法改為實體基類的FindByKey(前面某個版本增加,參數(shù)為Object),據(jù)說Delegate.CreateDelegate出來的委托會很慢
- * 實體元數(shù)據(jù)類Meta增加單對象實體緩存SingleCache,給SingleCacheInt和SingleCacheStr加上過期標(biāo)識,到v7.0將不再支持
- * 實體元數(shù)據(jù)類Meta增加OnDataChange的數(shù)據(jù)改變事件,并使用弱引用,當(dāng)該實體有數(shù)據(jù)改變后,觸發(fā)事件,可用于在外部清楚該對象的緩存
- * (重要更新)實體基類增加字典緩存Extends,用于存儲擴展屬性,并增加專屬的GetExtend方法用于獲取擴展屬性,向依賴實體類注冊數(shù)據(jù)更改事件
- * (重要更新)實體樹類升級為實體樹基類,所有具有樹形結(jié)構(gòu)數(shù)據(jù)的實體類,繼承自該類,享受樹形實體的各種功能
- * 實體基類增加虛擬的CreateXmlSerializer,允許實體類重載以改變Xml序列化行為,默認序列化行為改為序列化為特性
- * EntityList改變序列化行為,默認序列化為特性
- * EntityList判斷元素是否存在Contains方法改為Exists
- * EntityList增加多字段排序方法Sort,可用于多個字段排序
- * 修復(fù)快速訪問方法、屬性和字段所存在的問題,在實體基類索引器使用
- *
- * v5.9.2010.1020 修正Database中QueryCountFast的嚴重錯誤
- *
- * v5.8.2010.1018 增加實體樹接口IEntityTree,用于解決實體樹操作的一些共性問題,避免死循環(huán)
- *
- * v5.7.2010.0930 XField中增加一個Table屬性指向自己的XTable,創(chuàng)建XField時必須指定所屬XTable
- * 增加只讀列表,各配置項使用只讀列表返回,配置項自身檢測列表是否被修改
- * 實體操作接口增加Fields和FieldNames屬性
- *
- * v5.6.2010.0909 修改DAL,把QueryTimes和ExecuteTimes改為本線程的查詢次數(shù)和執(zhí)行次數(shù)
- * 修改Entity,Meta.Count返回表的總記錄數(shù)(快速),F(xiàn)indCount()使用普通方法查詢真實記錄數(shù)
- *
- * v5.5.2010.0903 實體操作接口IEntityOperate返回的實體集合改為EntityList<IEntity>,因為使用操作接口時一般不知道具體類型,如果知道就沒必要使用操作接口
- * 增加數(shù)據(jù)連接名映射的配置,允許通過配置修改某一個實體或者某一個連接名實際對應(yīng)的連接名
- * 修改實體緩存和單對象緩存,使得緩存的數(shù)據(jù)因連接名或表名不同而不同,避免不同連接名或表名時緩存串號的問題
- * 修改實體類結(jié)構(gòu)模型,比如Area:Area<Area>:Entity<Area>,使得實體類可以通過繼承實現(xiàn)二次擴展
- *
- * v5.4.2010.0830 數(shù)據(jù)架構(gòu)中的異步檢查BeginCheck當(dāng)啟用檢查時改為同步檢查Check,保證數(shù)據(jù)庫操作前先完成一次數(shù)據(jù)架構(gòu)檢查
- * 唯一鍵為自增且參數(shù)小于等于0時,返回空
- * 實體操作接口IEntityOperate增加ToList方法,實現(xiàn)把ICollection轉(zhuǎn)為List<IEntity>
- * 優(yōu)化Entity的FindAll方法,處理海量數(shù)據(jù)尾頁查詢時使用優(yōu)化算法
- *
- * v5.3.2010.0826 DAL增加CreateOperate方法,為數(shù)據(jù)表動態(tài)創(chuàng)建實體類操作接口,支持在沒有實體類的情況下操作數(shù)據(jù)庫
- * 該版本為不穩(wěn)定版本
- *
- * v5.2.2010.0726 IEntity接口增加SetItem方法,提供影響臟數(shù)據(jù)的弱類型數(shù)據(jù)設(shè)置
- * IEntityOperate接口增加Create方法,提供創(chuàng)建被類型實體對象的功能
- *
- * v5.1.2010.0709 增加實體接口、實體操作接口、實體基類的基類,提供弱類型的Orm支持
- *
- * v5.0.2010.0625 DAL優(yōu)化
- * 重新啟用授權(quán)管理
- * EntityList增加排序方法Sort
- *
- * v4.9.2010.0430 使用SelectBuilder來構(gòu)造SQL語句,用于各層之間傳遞,準(zhǔn)備將所有方法往SelectBuilder過度。該更新可能造成使用GroupBy的地方計算出錯
- *
- * v4.8.2010.0325 修改Entity索引器,新的快速調(diào)用方法在set的時候有問題
- * 增加常用查詢方法為Web方法
- *
- * v4.8.2010.0301 增加實體類多表支持和多數(shù)據(jù)庫支持
- * 暴露幾個常用的實體類靜態(tài)方法供WebService引用
- *
- * v4.7.2010.0130 數(shù)據(jù)架構(gòu)中識別表名時不應(yīng)該區(qū)分大小寫
- * Entity中增加MakeCondition方法,以便于構(gòu)造where語句
- *
- * v4.6.2009.1226 改善分頁算法,產(chǎn)生更簡單的分頁語句
- *
- * v4.5.2009.1127 增加單實體緩存
- *
- * v4.4.2009.1125 修改二級緩存,Entities改為EntityList類型,非空,支持FindAll操作
- *
- * v4.3.2009.1121 修正Entity中Save方法判斷自增字段不準(zhǔn)確的BUG
- *
- * v4.2.2009.1114 優(yōu)化SqlServer取架構(gòu)信息的性能,以及輸出的SQL的可讀性
- * 支持Sql2008,通過Sql2005類
- * 優(yōu)化QueryCount方法,產(chǎn)生更簡短的SQL
- *
- * v4.1.2009.1028 增加快速獲取單表總記錄數(shù)方法QueryCountFast,修改Entity,在記錄數(shù)大于1000時自動使用快速取總記錄數(shù)
- *
- * v4.0.2009.1011 增加實體類集合EntityList,Entity的所有FindAll返回EntityList
- * 增強數(shù)據(jù)架構(gòu)功能,支持Access、SQL2000、SQL2005
- *
- * v3.7.2009.0907 修正DatabaseSchema中的一個小錯誤
- *
- * v3.6.2009.0819 修正FindCount方法的錯誤
- *
- * v3.5.2009.0714 Config類輸出的FieldItem集合改為數(shù)組,防止被外部修改。
- * 所有Select語句,使用*表示所有列,而不是列出所有列名。
- *
- * v3.4.2009.0701 修正SqlServer 2000取主鍵的錯誤
- *
- * v3.3.2009.0628 修改DAL,屏蔽Web請求級緩存DB的方法,似乎Web下多線程很不穩(wěn)定,從而導(dǎo)致事務(wù)無法正常使用。
- *
- * v3.2.2009.0623 修改Oracle,重載GetTables方法,修正無法從Oracle數(shù)據(jù)庫取得構(gòu)架信息的錯誤
- *
- * v3.1.2009.0611 修改SqlServer類,使得每次返回構(gòu)架信息時,都是從數(shù)據(jù)庫取值。
- *
- * v3.0.2009.0608 元數(shù)據(jù)類Meta增加一個字段名列表屬性FieldNames
- * 調(diào)整DatabaseSchema類,新增字段時,直接設(shè)置默認值,否則對于非空字段,創(chuàng)建字段將會失敗
- * 數(shù)據(jù)構(gòu)架增加DatabaseSchema_Exclude配置項,用于指定要排除檢查的鏈接名。
- * Entity中,增加ToXml輸出的Xml的編碼為UTF8,增加FromXml反序列化,增加Clone方法和CloneEntity方法
- * Database中,增加事務(wù)計數(shù)字段,支持多級事務(wù)。
- * Entity中,集合運算返回值改為List<T>,而不是IList<T>,更方便調(diào)用
- * 在Database的QueryCount方法增加自動去除排序子句的功能
- * Entity中,增加ToString重載,默認顯示Name屬性
- * Entity中,Update時,增加了臟數(shù)據(jù)的判斷,非臟數(shù)據(jù)的字段不更新,由于該功能的增加將導(dǎo)致以前所有的實體都無法Update到數(shù)據(jù)庫,故版本改為3.0
- *
- * v2.3.2009.0530 修正非自增字段做主鍵時也調(diào)用InsertAndGetIdentity的錯誤。
- *
- * v2.2.2009.0527 數(shù)據(jù)表結(jié)構(gòu)中,增加Int16和Int64兩種類型
- *
- * v2.1.2009.0408 修正DAL中_DBs空引用的問題,可能是因為該成員是線程靜態(tài),并沒有在每一個線程上new一個對象。
- *
- * v2.0.2009.0408 增加數(shù)據(jù)架構(gòu)的功能。數(shù)據(jù)架構(gòu)可以實現(xiàn)通過實體類反向更新數(shù)據(jù)庫結(jié)構(gòu),不啟用時,僅把更新SQL寫入日志
- * 修正Access類使用當(dāng)前目錄時拼接路徑的錯誤。
- *
- * v1.2.2008.01.01 使用泛型基類重構(gòu)
- *
- * v1.1.2007.03.08 大量擴展功能,支持自定義表單、廣義單點登錄等項目
- * 完善對Oracle的支持,支持電力生產(chǎn)管理系統(tǒng)等項目
- * 完善對Sybase的支持,支持電力SCADA數(shù)據(jù)分析等項目
- *
- * v1.0.2005.10.01 創(chuàng)建項目
- * 支持C++客戶端網(wǎng)絡(luò)驗證系統(tǒng)等項目
- * 支持圖片驗證碼識別等項目
- */
小結(jié):淺談Orm框架XCode v3.5源碼發(fā)布的內(nèi)容介紹完了,希望本文對你有所幫助!