程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Dbml文件提取建表TSql-CodeSmith

Dbml文件提取建表TSql-CodeSmith

編輯:關於.NET

在昨天一個大學師弟,他問我能不能將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 --Code By  Wolf
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 using System;
2 using  System.Collections.Generic;
3 using System.Linq;
4 using  System.Text;
5
6 namespace DbmlToTable
7 {
8      class Program 
9     {
10         static void  Main(string[] args)
11         {
12              IDbTableCollectionHelper helper = new  DbTableCollectionHelper();
13              List<DBTable> collection = helper. 
14                  Transport(System.Xml.Linq.XElement.
15
16           Load (@"xxpath\MultipleDocument.Data\MultipleDocumentDB.dbml"));
17
1 8             CodeSmith.Engine.CodeTemplate template =  CodeSimthTemplateHelper. 
19                  CompileTemplate(@"DBMLToTable.cst", w => Console.WriteLine (w));
20             if (template != null)
21              {
22                  CodeSimthTemplateHelper.AddPropertyParams(template, new {  DbTableCollection = collection });
23                  string str = template.RenderToString();
24                  Console.WriteLine(str);
25                  //System.IO.File.AppendAllText(@"D:\1.sql", str);
26              }
27              Console.Read();
28         }
29
30 }
31
32
33
34

在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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved