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

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

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

  1. <%@ CodeTemplate Language="C#" TargetLanguage="C#" ResponseEncoding="UTF-8"%>
  2. <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="数据表" %>
  3. <%@ Assembly Name="SchemaExplorer" %>
  4. <%@ Import Namespace="SchemaExplorer" %>
  5.  
  6. <%for(int i=;i<SourceTable.Columns.Count;i++){%>
  7. <%=SourceTable.Columns[i].Name%>
  8. <%}%>

运行后得到

  1. Age
  2. ID
  3. IsOK
  4. Name
  5. Remark
  6. 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代码如下:

  1. <%@ CodeTemplate Language="C#" TargetLanguage="C#" ResponseEncoding="UTF-8"%>
  2. <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="数据表" %>
  3. <%@ Assembly Name="SchemaExplorer" %>
  4. <%@ Import Namespace="SchemaExplorer" %>
  5. <%@ Import Namespace="System.Data.OleDb" %>
  6. <%FixColumns();%>
  7.  
  8. <%for(int i=;i<SourceTable.Columns.Count;i++){%>
  9. <%=SourceTable.Columns[i].Name%>
  10. <%}%>
  11.  
  12. <script runat="template">
  13. //由于SourceTable.Columns的顺序默认是按字段名升序排列,因此需要根据"ORDINAL_POSITION"的值来重新排序
  14. public void FixColumns()
  15. {
  16. OleDbConnection connection = new OleDbConnection(SourceTable.Database.ConnectionString);
  17. connection.Open();
  18. DataTable schemaColumns = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new string[] { null, null, SourceTable.Name, null });
  19. connection.Close();
  20.  
  21. for(int i=schemaColumns.Rows.Count;i>;i--)
  22. {
  23. for(int j=;j<schemaColumns.Rows.Count;j++)
  24. {
  25. if(Convert.ToInt32(schemaColumns.Rows[j]["ORDINAL_POSITION"].ToString())==i)
  26. {
  27. int m=;
  28. for(m=;m<SourceTable.Columns.Count;m++)
  29. {
  30. if(SourceTable.Columns[m].Name==schemaColumns.Rows[j]["COLUMN_NAME"].ToString())
  31. {
  32. break;
  33. }
  34. }
  35. ColumnSchema col=SourceTable.Columns[m];
  36. SourceTable.Columns.RemoveAt(m);
  37. SourceTable.Columns.Insert(,col);
  38. }
  39. }
  40. }
  41. }
  42. </script>

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

CodeSmith操作Access时字段的排序问题的更多相关文章

  1. C#操作Access时Parameters集合的使用方法(转)

    按照C#操作Sql Server数据库的方式是不一样的,使用时发现占位符数据会混乱. 查阅相关资料及测试后,总结出这样一套使用方法. 方法: public bool TsqlExecute(strin ...

  2. MFC通过ADO操作Access数据库

    我在<VC知识库在线杂志>第十四期和第十五期上曾发表了两篇文章——“直接通过ODBC读.写Excel表格文件”和“直接通过DAO读.写Access文件”,先后给大家介绍了ODBC和DAO两 ...

  3. 直接通过ADO操作Access数据库

    我在<VC知识库在线杂志>第十四期和第十五期上曾发表了两篇文章——“直接通过ODBC读.写Excel表格文件”和“直接通过DAO读.写Access文件”,先后给大家介绍了ODBC和DAO两 ...

  4. C#操作access和SQL server数据库代码实例

    在C#的学习中,操作数据库是比较常用的技术,而access和sql server 数据库的操作却有着不同.那么,有哪些不同呢? 首先,需要引用不同的类.因为有着不同的数据引擎. access:usin ...

  5. C#操作Access的一些小结

    C#操作Access的一些小结 好久没有写blog,感觉今年一年都没怎么真正开心过,整天有一些事围绕在身边,使心情难以平静下来,真正写点有意义的东西.博客园是天天看的,看得多,写的少,偶尔也是Copy ...

  6. C#操作Access

    C#操作Access数据库的基础知识浅析 C#操作Access数据库的基础知识都有什么呢? C#操作Access数据库的基础知识1. 通过ADO.NET的OleDb相关类来操作Access 主要知识点 ...

  7. 基于指纹考勤机的真实的PHP操作Access数据库成功案例(最终实现) 2011-11-2v

    听了我的建议,我们单位的食堂准备使用一台指纹考勤机统计吃饭人次,这样院里好给食堂的承包人以相应饭补.以前买过一台彩屏指纹机,数据库是access的,今儿又买了一台准备放到食堂里,而且考虑到停电,还特地 ...

  8. C#操作access练习

    ORM框架使用dapper,dapper不仅能操作sqlserver,也能操作access,下面为基本代码: OleDbConnection strConnection = new OleDbConn ...

  9. JavaScript操作数据库JS操作Access数据库

    avaScript操作数据库JS操作Access数据库,跟其他语言操作差不多,总结了一下习惯代码,仅供参考学习.现在在F盘有文件abc.mdf,表名为Student,一共2个字段,Id数字类型主键,s ...

随机推荐

  1. yii2解决百度编辑器umeditor图片上传问题

    作者:白狼 出处:http://www.manks.top/article/yii2_umeditor_upload本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原 ...

  2. [20140117]疑似checkpoint堵塞数据库连接

    注:这个说法是不成立的,问题已经解决,但是无法正确的定位到具体什么原因:[20140702]奇怪的应用程序超时 背景: 开发通过应用程序的日志发现间歇性的出现,数据库连接超时 原因: 只能大概猜测,没 ...

  3. cocos2d之json使用实例

    前端使用: json管理器中函数解析: 对宠物技能map的定义: 宠物技能表单--数据的基础定义:

  4. Android系统自带样式(android:theme)详解-(转)

    android:theme="@android:style/Theme.Dialog" : Activity显示为对话框模式 android:theme="@androi ...

  5. android java substring说明

    substring(参数)是java中截取字符串的一个方法有两种传参方式一种是public String substring(int beginIndex)返回一个新的字符串,它是此字符串的一个子字符 ...

  6. android 实现ImageView按压效果和解决背景图片拉申问题

    建立一个.XML文件,名为:image_tab_bg.xml <?xml version="1.0" encoding="utf-8"?> < ...

  7. AWS国际版的Route 53和CloudFront

    注册AWS国际版账号后,却发现Route 53和CloudFront功能是无法使用的.于是提交了一个Service Request,得到的答复是这两个功能需要验证后才能激活. 在控制台中点击进入Rou ...

  8. 思科ACI是一种什么样的技术?

    术语: SDN:Software Defined Network,软件定义网络 ACI:Application Centric Infrastracture,以应用为中心的基础网络架构 Fabric: ...

  9. spring mvc拦截器

    Java里的拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取act ...

  10. Codeforces Round #371 (Div. 2)E. Sonya and Problem Wihtout a Legend[DP 离散化 LIS相关]

    E. Sonya and Problem Wihtout a Legend time limit per test 5 seconds memory limit per test 256 megaby ...