CodeSmith操做Access時字段的排序問題

最近在用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值從小到大排序了。排序

相關文章
相關標籤/搜索