最近在用CodeSmith操做寫ACCESS數據庫的代碼模版,發現CodeSmith默認的字段順序與ACCESS中表的字段順序不一致。數據庫
首先在ACCESS數據庫中建一個測試表Test,並添加ID、Name等幾個字段,以下圖所示:ide
而後在CodeSmith中新建一個模版,並循環輸出全部字段名測試
<%@ CodeTemplate Language="C#" TargetLanguage="C#" ResponseEncoding="UTF-8"%> <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="數據表" %> <%@ Assembly Name="SchemaExplorer" %> <%@ Import Namespace="SchemaExplorer" %> <%for(int i=0;i<SourceTable.Columns.Count;i++){%> <%=SourceTable.Columns[i].Name%> <%}%>
運行後獲得ui
Age
ID
IsOK
Name
Remark
Time
咱們能夠看到,字段是按照字典順序排序的,而不是實際數據表中的順序。雖然這不影響什麼,可是一想到自動生成的MODEL層的字段和數據表的不對應,總感受不太爽。
我甚至將SourceTable.Columns[i].ExtendedProperties這個擴展屬性所有輸出,也沒有獲得什麼有用的信息。spa
後來無心中,我在.NET的 OleDbConnection.GetOleDbSchemaTable中獲得了字段的順序,新建一個winform項目,代碼以下code
1 string accessConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Database Password=123456;Data Source=c:\\db1.mdb;Persist Security Info=True"; 2 OleDbConnection connection = new OleDbConnection(accessConnection); 3 connection.Open(); 4 DataTable schemaColumns = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new string[] { null, null, "test", null }); 5 dataGridView2.DataSource = schemaColumns; 6 connection.Close();
我將GetOleDbSchemaTable獲取到信息都綁定到一個DataGridView控件中,這樣對裏面的數據能夠有一個比較直觀的瞭解
orm
終於看到了字段真正順序!那麼接下來的事情就比較好辦了,咱們要在CodeSmith中獲取這個SchemaTable,而後根據ORDINAL_POSITION的值從新對SourceTable.Columns進行排序,這樣後面編寫代碼模版的時候,字段順序就是正常的了。CodeSmith代碼以下:blog
<%@ CodeTemplate Language="C#" TargetLanguage="C#" ResponseEncoding="UTF-8"%> <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="數據表" %> <%@ Assembly Name="SchemaExplorer" %> <%@ Import Namespace="SchemaExplorer" %> <%@ Import Namespace="System.Data.OleDb" %> <%FixColumns();%> <%for(int i=0;i<SourceTable.Columns.Count;i++){%> <%=SourceTable.Columns[i].Name%> <%}%> <script runat="template"> //因爲SourceTable.Columns的順序默認是按字段名升序排列,所以須要根據"ORDINAL_POSITION"的值來從新排序 public void FixColumns() { OleDbConnection connection = new OleDbConnection(SourceTable.Database.ConnectionString); connection.Open(); DataTable schemaColumns = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new string[] { null, null, SourceTable.Name, null }); connection.Close(); for(int i=schemaColumns.Rows.Count;i>0;i--) { for(int j=0;j<schemaColumns.Rows.Count;j++) { if(Convert.ToInt32(schemaColumns.Rows[j]["ORDINAL_POSITION"].ToString())==i) { int m=0; for(m=0;m<SourceTable.Columns.Count;m++) { if(SourceTable.Columns[m].Name==schemaColumns.Rows[j]["COLUMN_NAME"].ToString()) { break; } } ColumnSchema col=SourceTable.Columns[m]; SourceTable.Columns.RemoveAt(m); SourceTable.Columns.Insert(0,col); } } } } </script>
代碼不難理解,我用了相似插入排序的思路,從排序最後的字段開始往前查找(即ORDINAL_POSITION值從最大到最小),查找到了後就插入到SourceTable.Columns集合的最前面。這樣到最後的結果就是SourceTable.Columns集合按ORDINAL_POSITION值從小到大排序了。排序