生活随笔
收集整理的這篇文章主要介紹了
Dbml文件提取建表TSql-CodeSmith
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在昨天一個大學師弟,他問我能不能將LinqToSql文件轉化為創建表的TSql語句,他是剛開始學習.NET,所以在網上下些示例看,但苦于沒有數據庫。所以就有了這一篇博客,作為我的Code生成技術的CodeSimth的最后一篇示例。在下一步Code 生成技術將轉到Microsoft的T4模板,Code生成技術目前完成的有CodeDom,CodeSmith模板,高手請不要拍磚,請直接跳過。
???? 在Linq2Sql的Dbml文件其實就是一個Xml文件,記錄著數據庫與生成Linq2SqlCode的數據信息,所以轉化為TSql沒有什么說的。我們需要提取其中的數據庫信息,在轉化為我們的Tsql,在這里建立了DBTable、DBColumn、DBAssociation三個實體類:代碼
?1?using?System;? ???2?using?System.Collections.Generic;? ???3?using?System.Linq;? ???4?using?System.Text;? ???5? ???6?namespace?DbmlToTable? ???7?{? ? ??8?????public?class?DBTable? ? ??9?????{? ??10? ? ?11?????????public?DBTable()? ? ?12?????????{? ??13?????????????Columns?=?new?List<DBColumn>();? ??14?????????????this.Associations?=?new?List<DBAssociation>();? ??15?????????}? ??16? ? ?17?????????public?string?TableName? ? ?18?????????{? ??19?????????????get;? ? ?20?????????????set;? ? ?21?????????}? ??22? ? ?23?????????public?List<DBColumn>?Columns? ? ?24?????????{? ??25?????????????get;? ? ?26?????????????set;? ? ?27?????????}? ??28? ? ?29?????????public?List<DBAssociation>?Associations? ? ?30?????????{? ??31?????????????get;? ? ?32?????????????set;? ? ?33?????????}? ??34? ??35?????}? ??36? ? ?37?????public?class?DBColumn? ? ?38?????{? ? ?39?????????public?string?Name? ? ?40?????????{? ??41?????????????get;? ? ?42?????????????set;? ? ?43?????????}? ??44? ? ?45?????????public?string?DBType? ? ?46?????????{? ??47?????????????get;? ? ?48?????????????set;? ? ?49?????????}? ??50? ? ?51?????????public?bool?IsPrimaryKey? ? ?52?????????{? ??53?????????????get;? ? ?54?????????????set;? ? ?55?????????}? ??56? ? ?57?????????public?bool?IsDbGenerated? ? ?58?????????{? ??59?????????????get;? ? ?60?????????????set;? ? ?61?????????}? ??62? ? ?63?????????public?bool?CanBeNull? ? ?64?????????{? ??65?????????????get;? ? ?66?????????????set;? ? ?67?????????}? ??68?????}? ??69? ? ?70?????public?class?DBAssociation? ? ?71?????{? ? ?72?????????public?string?Name? ? ?73?????????{? ??74?????????????get;? ? ?75?????????????set;? ? ?76?????????}? ??77? ? ?78?????????public?string?ThisKey? ? ?79?????????{? ??80?????????????get;? ? ?81?????????????set;? ? ?82?????????}? ??83? ? ?84?????????public?string?OtherKey? ? ?85?????????{? ??86?????????????get;? ? ?87?????????????set;? ? ?88?????????}? ??89? ? ?90?????????public?bool?IsForeignKey? ? ?91?????????{? ??92?????????????get;? ? ?93?????????????set;? ? ?94?????????}? ??95?????}? ??96? ? ?97?????public?class?DBTableHlper? ? ?98?????{? ? ?99?????????public?static?DBTable?GetAssociationTable(List<DBTable>?collection,string?assName)? ? 100?????????{? ?101? ? 102?????????????return?collection.Find(t?=>?t.Associations.Find(a?=>?!a.IsForeignKey?&&?a.Name?==?assName)?!=?null);? ? 103?????????}? ?104?????}? ?105?} ?106? ?107? ?復制代碼? ?? 其中DBTableHlper是由于我的Codesimth是2.0版本的,不能用lamdam表達式,所以我將它編譯在程序集里面。
?? 建立了一個 將我們的dbml文件xml Document轉化為實體類輔助類:
代碼? ???1?using?System;? ??2?using?System.Collections.Generic;? ??3?using?System.Linq;? ??4?using?System.Text;? ??5?using?System.Xml;? ??6?using?System.Xml.Linq;? ??7? ??8?namespace?DbmlToTable? ??9?{? ?10? ? 11?????public?interface?IDbTableCollectionHelper? ? 12?????{? ?13?????????List<DBTable>?Transport(XElement?element);? ?14?????}? ?15? ? 16?????public?class?DbTableCollectionHelper?:?IDbTableCollectionHelper? ? 17?????{? ?18?????????#region?IDbTableCollectionHelper?成員? ?19? ? 20?????????public?List<DBTable>?Transport(XElement?element)? ? 21?????????{? ?22?????????????List<DBTable>?collection?=?new?List<DBTable>();? ? 23?????????????var?tables?=?element.Elements(XName.Get("Table",?"http://schemas.microsoft.com/linqtosql/dbml/2007%22));? ? 24?????????????foreach?(var?tab?in?tables)? ? 25?????????????{? ? 26?????????????????DBTable?t?=?new?DBTable()?{?TableName?=?tab.Attribute("Name").Value?};? ? 27?????????????????var?cols?=?tab.Element(XName.Get("Type",?"http://schemas.microsoft.com/linqtosql/dbml/2007%22)).Elements(XName.Get(%22Column%22,?"http://schemas.microsoft.com/linqtosql/dbml/2007%22));? ? 28?????????????????foreach?(var?col?in?cols)? ? 29?????????????????{? ?30?????????????????????DBColumn?c?=?new?DBColumn()? ?31?????????????????????{? ? 32?????????????????????????CanBeNull?=?col.Attribute("CanBeNull")?!=?null???col.Attribute("CanBeNull").Value.ToLower()?==?"true"?:?false,? ? 33?????????????????????????DBType?=?col.Attribute("DbType")?!=?null???col.Attribute("DbType").Value?:?"",? ? 34?????????????????????????IsDbGenerated?=?col.Attribute("IsDbGenerated")?!=?null???col.Attribute("IsDbGenerated").Value.ToLower()?==?"true"?:?false,? ? 35?????????????????????????IsPrimaryKey?=?col.Attribute("IsPrimaryKey")?!=?null???col.Attribute("IsPrimaryKey").Value.ToLower()?==?"true"?:?false,? ? 36?????????????????????????Name?=?col.Attribute("Name")?!=?null???col.Attribute("Name").Value?:?""? ? 37?????????????????????};? ? 38?????????????????????t.Columns.Add(c);? ? 39?????????????????}? ?40? ? 41?????????????????var?ass?=?tab.Element(XName.Get("Type",?"http://schemas.microsoft.com/linqtosql/dbml/2007%22)).Elements(XName.Get(%22Association%22,?"http://schemas.microsoft.com/linqtosql/dbml/2007%22));? ? 42?????????????????foreach?(var?item?in?ass)? ? 43?????????????????{? ?44?????????????????????DBAssociation?a?=?new?DBAssociation()? ?45?????????????????????{? ? 46?????????????????????????Name?=?item.Attribute("Name")?!=?null???item.Attribute("Name").Value?:?"",? ? 47?????????????????????????OtherKey?=?item.Attribute("OtherKey")?!=?null???item.Attribute("OtherKey").Value?:?"",? ? 48?????????????????????????ThisKey?=?item.Attribute("ThisKey")?!=?null???item.Attribute("ThisKey").Value?:?"",? ? 49?????????????????????????IsForeignKey?=?item.Attribute("IsForeignKey")?!=?null???item.Attribute("IsForeignKey").Value.ToLower()?==?"true"?:?false? ? 50?????????????????????};? ? 51?????????????????????t.Associations.Add(a);? ? 52?????????????????}? ? 53?????????????????collection.Add(t);? ? 54?????????????}? ? 55?????????????return?collection;? ? 56?????????}? ?57? ?58?????????#endregion? ?59?????}? ?60?} ?61? ?62? ?復制代碼?? 在轉化為我們的實體類,我們剩下的就是編寫我們的CodeSmith模板了(更多知識可以參考CodeSmith模板):
代碼? ?? ?1?<%@?CodeTemplate?Language="C#"?TargetLanguage="Text"?Src=""?Inherits=""?Debug="False"?Description="Template?description?here."?%>? ? ?2? ? ?3?<%@?Import?NameSpace="System"?%>? ? ?4?<%@?Import?NameSpace="System.Xml"?%>? ? ?5?<%@?Import?NameSpace="System.Text"?%>? ? ?6?<%@?Import?NameSpace="System.Collections.Generic"?%>? ? ?7?<%@?Assembly?Name="DbmlToTable"?%>? ? ?8? ? ?9?? 10?<script?runat="template">? ? 11?private?List<DbmlToTable.DBTable>?_DbTableCollection;? ? 12?public?List<DbmlToTable.DBTable>?DbTableCollection? ? 13?{? ?14?????get? ?15?????{? ? 16?????????return?_DbTableCollection;? ? 17?????}? ? 18?????set???? ? 19?????{? ?20?????????_DbTableCollection=value;? ?21?????}? ?22?}? ?23? ? 24?public??string?GeneratorTableSql(List<DbmlToTable.DBTable>?collection)? ? 25?{? ?26?????StringBuilder?sb?=?new?StringBuilder();? ?27?????StringBuilder?sbAssocation?=?new?StringBuilder();? ? 28?????foreach?(DbmlToTable.DBTable?item?in?collection)? ? 29?????{? ?30?????????List<string>?cols?=?new?List<string>();? ? 31?????????foreach?(DbmlToTable.DBColumn??col?in?item.Columns)? ? 32?????????{? ? 33?????????????cols.Add(string.Format("{0}?{1}?{2}?",?col.Name,?col.DBType,?col.IsPrimaryKey???"PRIMARY?KEY?"?:?""));? ? 34?????????}? ? 35?????????sb.AppendFormat("\r\nCREATE?TABLE?{0}?\r\n(\r\n{1}\r\n)",?item.TableName,?string.Join(",\r\n",?cols.ToArray()));? ? 36? ? 37?????????foreach?(DbmlToTable.DBAssociation?ass?in?item.Associations)? ? 38?????????{? ?39?????????????if?(ass.IsForeignKey)? ?40?????????????{? ? 41?????????????????DbmlToTable.DBTable?tab?=?DbmlToTable.DBTableHlper.GetAssociationTable(collection,ass.Name);? ? 42?????????????????if?(tab?!=?null)? ? 43?????????????????{? ?44?????????????????????sbAssocation.AppendLine();? ? 45?????????????????????sbAssocation.AppendFormat(@"ALTER?TABLE?{0}??WITH?NOCHECK?ADD??CONSTRAINT?{1}?FOREIGN?KEY({2})?REFERENCES?{3}?({4})",? ? 46?????????????????????????item.TableName,?"FK_"?+?ass.Name,?ass.ThisKey,?tab.TableName,?ass.OtherKey);? ? 47?????????????????}? ?48?????????????}? ?49?????????}? ?50?????}? ?51? ? 52?????return?sb.ToString()?+?"\r\n"?+?sbAssocation.ToString();? ? 53?}? ?54?</script>? ?55?<%=?this.GeneratorTableSql(_DbTableCollection)?%> ?56? ?57? ?復制代碼?在codeSimth中我們建立了一個集合屬性傳遞實體類DBTable和一個轉化TSql輔助方法.
????? 在控制臺調用編譯模板以及輸出:
代碼? ? ?1?<%@?CodeTemplate?Language="C#"?TargetLanguage="Text"?Src=""?Inherits=""?Debug="False"?Description="Template?description?here."?%>? ? ?2? ? ?3?<%@?Import?NameSpace="System"?%>? ? ?4?<%@?Import?NameSpace="System.Xml"?%>? ? ?5?<%@?Import?NameSpace="System.Text"?%>? ? ?6?<%@?Import?NameSpace="System.Collections.Generic"?%>? ? ?7?<%@?Assembly?Name="DbmlToTable"?%>? ? ?8? ? ?9?? 10?<script?runat="template">? ? 11?private?List<DbmlToTable.DBTable>?_DbTableCollection;? ? 12?public?List<DbmlToTable.DBTable>?DbTableCollection? ? 13?{? ?14?????get? ?15?????{? ? 16?????????return?_DbTableCollection;? ? 17?????}? ? 18?????set???? ? 19?????{? ?20?????????_DbTableCollection=value;? ?21?????}? ?22?}? ?23? ? 24?public??string?GeneratorTableSql(List<DbmlToTable.DBTable>?collection)? ? 25?{? ?26?????StringBuilder?sb?=?new?StringBuilder();? ?27?????StringBuilder?sbAssocation?=?new?StringBuilder();? ? 28?????foreach?(DbmlToTable.DBTable?item?in?collection)? ? 29?????{? ?30?????????List<string>?cols?=?new?List<string>();? ? 31?????????foreach?(DbmlToTable.DBColumn??col?in?item.Columns)? ? 32?????????{? ? 33?????????????cols.Add(string.Format("{0}?{1}?{2}?",?col.Name,?col.DBType,?col.IsPrimaryKey???"PRIMARY?KEY?"?:?""));? ? 34?????????}? ? 35?????????sb.AppendFormat("\r\nCREATE?TABLE?{0}?\r\n(\r\n{1}\r\n)",?item.TableName,?string.Join(",\r\n",?cols.ToArray()));? ? 36? ? 37?????????foreach?(DbmlToTable.DBAssociation?ass?in?item.Associations)? ? 38?????????{? ?39?????????????if?(ass.IsForeignKey)? ?40?????????????{? ? 41?????????????????DbmlToTable.DBTable?tab?=?DbmlToTable.DBTableHlper.GetAssociationTable(collection,ass.Name);? ? 42?????????????????if?(tab?!=?null)? ? 43?????????????????{? ?44?????????????????????sbAssocation.AppendLine();? ? 45?????????????????????sbAssocation.AppendFormat(@"ALTER?TABLE?{0}??WITH?NOCHECK?ADD??CONSTRAINT?{1}?FOREIGN?KEY({2})?REFERENCES?{3}?({4})",? ? 46?????????????????????????item.TableName,?"FK_"?+?ass.Name,?ass.ThisKey,?tab.TableName,?ass.OtherKey);? ? 47?????????????????}? ?48?????????????}? ?49?????????}? ?50?????}? ?51? ? 52?????return?sb.ToString()?+?"\r\n"?+?sbAssocation.ToString();? ? 53?}? ?54?</script>? ?55?<%=?this.GeneratorTableSql(_DbTableCollection)?%> ?56? ?57? ?復制代碼 ??? 在CodeSimth中就是這么簡單,生成相應的模板代碼(個人理解CodeSmith就是把代碼作為字符串輸出)。
在上面到我的CodeSmith模板編譯輔助類,在上一篇通過代碼生成機制實現強類型編程-CodeSmith版也有,在這里也附帶上:需要引用CodeSmith.Engine.dll.
代碼? ???1?using?System;? ??2? ??3?using?System.Collections.Generic;? ??4? ??5?using?System.Linq;? ??6? ??7?using?System.Text;? ??8? ??9?using?CodeSmith.Engine;? ?10? ?11?using?Wolf.NameValueDictionary;? ?12? ?13?namespace?DbmlToTable? ?14? ?15?{? ?16? ? 17?public?class?CodeSimthTemplateHelper? ? 18? ?19?{? ?20? ? 21??????public?static?CodeTemplate?CompileTemplate(string?templateName,?Action?errorWriter)? ? 22? ?23??????{? ?24? ?25????????????CodeTemplateCompiler?compiler?=?new?CodeTemplateCompiler(templateName);?compiler.Compile();? ?26? ? 27???????????if?(compiler.Errors.Count?==?0)? ? 28? ?29????????????{? ?30? ? 31????????????return?compiler.CreateInstance(); ? 32? ?33????????????}? ?34? ? 35????????else? ? 36? ?37??????????{? ?38? ? 39????????????for?(int?i?=?0;?i?<?compiler.Errors.Count;?i++)? ? 40? ?41?????????{? ?42? ?43?????????????errorWriter(compiler.Errors[i].ToString());? ?44? ?45??????????}? ?46? ? 47?????????return?null;? ? 48? ?49????????}? ?50? ?51?}? ?52? ?53?? ?54? ? 55?public?static?void?AddPropertyParams(CodeTemplate?template,object?param)? ? 56? ?57?{? ?58? ?59???????NameValueDictionary?dict?=?new?NameValueDictionary<object>(param); ?60? ?61????????AddPropertyParams(template,?dict); ?62? ?63?} ?64? ?65?? ?66? ? 67?public?static?void?AddPropertyParams(CodeTemplate?template,?NameValueDictionary<object>?param) ? 68? ?69?{ ?70? ?71???????????NameValueDictionary<object>?dict?=?new?NameValueDictionary<object>(param); ?72? ? 73???????????foreach?(var?item?in?dict.Keys) ? 74? ?75???????????{ ?76? ?77?????????????????template.SetProperty(item,?dict[item]); ?78? ?79????????????} ?80? ?81?} ?82? ?83?} ?84? ?85?} ?86? ?復制代碼??
?本文轉自 破狼 51CTO博客,原文鏈接:http://blog.51cto.com/whitewolfblog/834728,如需轉載請自行聯系原作者
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的Dbml文件提取建表TSql-CodeSmith的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。