好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

CodeSmith操作Access时字段的排序问题

最近在用CodeSmith操作写ACCESS数据库的代码模版,发现CodeSmith默认的字段顺序与ACCESS中表的字段顺序不一致。 首先在ACCESS数据库中建一个测试表Test,并添加ID、Name等几个字段,如下图所示: 然后在CodeSmith中新建一个模版,并循环 输出所有字段名 %@ Cod

最近在用CodeSmith操作写ACCESS数据库的代码模版,发现CodeSmith默认的字段顺序与ACCESS中表的字段顺序不一致。

首先在ACCESS数据库中建一个测试表Test,并添加ID、Name等几个字段,如下图所示:

然后在CodeSmith中新建一个模版,并循环 输出所有字段名

  "  C#  "  TargetLanguage= "  C#  "  ResponseEncoding= "  UTF-8  " %>
 "  SourceTable  "  Type= "  SchemaExplorer.TableSchema  "  Category= "  Context  "  Description= "  数据表  "  %>
 "  SchemaExplorer  "  %>
 "  SchemaExplorer  "  %>

 for ( int  i= 0 ;i 
 
  

运行后得到

 Age
ID
IsOK
Name
Remark
Time  

我们可以看到,字段是按照字典顺序排序的,而不是实际数据表中的顺序。虽然这不影响什么,但是一想到自动生成的MODEL层的字段和数据表的不对应,总感觉不太爽。
我甚至将SourceTable.Columns[i].ExtendedProperties这个扩展属性全部 输出,也没有得到什么有用的信息。

后来无意中,我在.NET的 OleDbConnection.GetOleDbSchemaTable中得到了字段的顺序,新建一个winform项目,代码如下

 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控件中,这样对里面的数据可以有一个比较直观的了解

终于看到了字段真正顺序!那么接下来的事情就比较好办了,我们要在CodeSmith中获取这个SchemaTable,然后根据ORDINAL_POSITION的值重新对SourceTable.Columns进行排序,这样后面编写代码模版的时候,字段顺序就是正常的了。CodeSmith代码如下:

 "  C#  "  TargetLanguage= "  C#  "  ResponseEncoding= "  UTF-8  " %>
 "  SourceTable  "  Type= "  SchemaExplorer.TableSchema  "  Category= "  Context  "  Description= "  数据表  "  %>
 "  SchemaExplorer  "  %>
 "  SchemaExplorer  "  %>
 "  System.Data.OleDb  "  %>
 

 for ( int  i= 0 ;i 
 
 

 "  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 )
        {
              if (Convert.ToInt32(schemaColumns.Rows[j][ "  ORDINAL_POSITION  " ].ToString())== i)
            {
                  int  m= 0  ;
                  for (m= 0 ;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);
            }
        }
    }
}
   

代码不难理解,我用了类似插入排序的思路,从排序最后的字段开始往前查找(即ORDINAL_POSITION值从最大到最小),查找到了后就插入到SourceTable.Columns集合的最前面。这样到最后的结果就是SourceTable.Columns集合按ORDINAL_POSITION值从小到大排序了。

查看更多关于CodeSmith操作Access时字段的排序问题的详细内容...

  阅读:46次