说明:

1,采用 dynamic 调用 COM 组件,适用于 .NET 4.0 以上支持 dynamic 版本的才可以;
2,执行速度不敢恭维,只是因为要用于 Silverlight OOB 模式中才研究一二;
3,测试环境 .net 4.5 + Silverlight 5.0 + Visual Studio 2013
4,见如下 helper 类(需引用 using System.Runtime.InteropServices.Automation;):
  1. public class SLAccessHelper
  2. {
  3. private dynamic m_AccessApp;// Access.Application
  4. private dynamic m_Database;// Database
  5. private dynamic m_Recordset;
  6.  
  7. /// <summary>
  8. /// 构造函数
  9. /// </summary>
  10. /// <param name="visible">Access是否可见</param>
  11. public SLAccessHelper(bool visible)
  12. {
  13. m_AccessApp = AutomationFactory.CreateObject("Access.Application");
  14. m_AccessApp.Visible = visible;
  15. }
  16.  
  17. /// <summary>
  18. /// 打开数据库
  19. /// </summary>
  20. /// <param name="filePath">Access数据库文件路径</param>
  21. /// <param name="exclusive">是否共享</param>
  22. /// <param name="bstrPassword">密码</param>
  23. public void OpenDb(string filePath, bool exclusive = false, string bstrPassword = "")
  24. {
  25. m_AccessApp.OpenCurrentDatabase(filePath, exclusive, bstrPassword);
  26. m_Database = m_AccessApp.CurrentDb();
  27. }
  28.  
  29. /// <summary>
  30. /// 获取当前数据库中所有表名称集合
  31. /// </summary>
  32. /// <returns>所有表名称集合</returns>
  33. public List<string> GetTableNames()
  34. {
  35. List<string> tableNames = new List<string>();
  36. dynamic tableDefs = m_Database.TableDefs;
  37. foreach (dynamic tableDef in tableDefs)
  38. {
  39. tableNames.Add(tableDef.Name);
  40. }
  41.  
  42. return tableNames;
  43. }
  44.  
  45. /// <summary>
  46. /// 加载表数据
  47. /// </summary>
  48. /// <param name="tableName">表名称</param>
  49. /// <returns>表数据</returns>
  50. public List<List<string>> LoadTable(string tableName)
  51. {
  52. dynamic recordSet = m_Database.OpenRecordset(tableName);
  53. int fieldsCount = recordSet.Fields.Count;
  54. List<List<string>> data = new List<List<string>>();
  55. if (fieldsCount > )
  56. {
  57. try
  58. {
  59. List<string> fieldNames = new List<string>();
  60. for (int i = ; i < fieldsCount; i++)
  61. {
  62. fieldNames.Add(recordSet.Fields[i].Name);
  63. }
  64. data.Add(fieldNames);
  65. if (!recordSet.EOF)
  66. {
  67. recordSet.MoveFirst();
  68. while (!recordSet.EOF)
  69. {
  70. object[] dataRow = recordSet.GetRows();// 返回一维数组
  71. List<string> dataRowStr = new List<string>();
  72. for (int i = ; i < dataRow.Length; i++)
  73. {
  74. dataRowStr.Add(dataRow[i] == null ? "" : dataRow[i].ToString());
  75. }
  76. data.Add(dataRowStr);
  77. }
  78. }
  79. }
  80. catch (Exception ex)
  81. {
  82. throw new Exception(ex.Message);
  83. }
  84. finally
  85. {
  86. if (recordSet != null)
  87. {
  88. recordSet.Close();
  89. ((IDisposable)recordSet).Dispose();
  90. recordSet = null;
  91. }
  92. }
  93. }
  94.  
  95. return data;
  96. }
  97.  
  98. /// <summary>
  99. /// 添加新纪录
  100. /// </summary>
  101. /// <param name="tableName">表格名称</param>
  102. /// <param name="data">数据</param>
  103. public void AddNewRecord(string tableName, List<Dictionary<string, object>> data)
  104. {
  105. try
  106. {
  107. m_Recordset = m_Database.OpenRecordset(tableName, );// 1=RecordsetTypeEnum.dbOpenTable
  108. int fieldsCount = m_Recordset.Fields.Count;
  109. List<string> fieldNames = new List<string>();
  110. for (int i = ; i < fieldsCount; i++)
  111. {
  112. fieldNames.Add(m_Recordset.Fields[i].Name);
  113. }
  114. for (int rowIndex = ; rowIndex < data.Count; rowIndex++)
  115. {
  116. m_Recordset.AddNew();
  117. foreach (string fieldName in fieldNames)
  118. {
  119. m_Recordset.Fields[fieldName].Value = data[rowIndex][fieldName];
  120. }
  121. m_Recordset.Update();
  122. }
  123. }
  124. catch(Exception ex)
  125. {
  126. throw new Exception(ex.Message);
  127. }
  128. finally
  129. {
  130. if (m_Recordset != null)
  131. {
  132. m_Recordset.Close();
  133. ((IDisposable)m_Recordset).Dispose();
  134. m_Recordset = null;
  135. }
  136. }
  137. }
  138.  
  139. /// <summary>
  140. /// 更新表格数据
  141. /// </summary>
  142. /// <param name="tableName">表格名称</param>
  143. /// <param name="data">数据</param>
  144. public void UpdateTable(string tableName, List<Dictionary<string, string>> data)
  145. {
  146. try
  147. {
  148. m_Recordset = m_Database.OpenRecordset(tableName, );// 1=RecordsetTypeEnum.dbOpenTable
  149. m_Recordset.MoveFirst();
  150. for (int rowIndex = ; rowIndex < data.Count; rowIndex++)
  151. {
  152. m_Recordset.Edit();
  153. foreach (string fieldName in data[rowIndex].Keys)
  154. {
  155. m_Recordset.Fields[fieldName].Value = data[rowIndex][fieldName];
  156. }
  157. m_Recordset.Update();
  158. m_Recordset.MoveNext();
  159. }
  160. }
  161. catch (Exception ex)
  162. {
  163. throw new Exception(ex.Message);
  164. }
  165. finally
  166. {
  167. if (m_Recordset != null)
  168. {
  169. m_Recordset.Close();
  170. ((IDisposable)m_Recordset).Dispose();
  171. m_Recordset = null;
  172. }
  173. }
  174. }
  175.  
  176. /// <summary>
  177. /// 关闭
  178. /// </summary>
  179. public void Close()
  180. {
  181. if (m_Database != null)
  182. {
  183. m_Database.Close();
  184. ((IDisposable)m_Database).Dispose();
  185. m_Database = null;
  186. }
  187. if (m_AccessApp != null)
  188. {
  189. m_AccessApp.CloseCurrentDatabase();
  190. // m_AccessApp.Quit();// 导致最后会弹出Access主页面
  191. ((IDisposable)m_AccessApp).Dispose();
  192. m_AccessApp = null;
  193. }
  194. GC.Collect();
  195. }
  196. }
 
通过 dynamic 构建的 COM 对象,在使用完成后都要手动关闭销毁,比如代码中的 m_AccessApp, m_Database, m_Recordset 三个对象,否则只是将 m_AccessApp 关闭清空释放掉,Access 进程还是无法关闭,在程序关闭之前,始终都会有一个空白的无法关闭的 Access 界面;

在循环中处理 dynamic 和 C# 类型转换会降低程序执行效率,就比如像 GetTableNames 方法中循环遍历表名,都要花两三秒时间,所以尽量像 object[] dataRow = recordSet.GetRows(); 直接获取其中的所有数据,然后再遍历处理,会极大提高执行效率;

要修改 Access 中的数据时,一定要先 m_Recordset.Edit(); 才会允许你编辑其中的内容;

[Access] C# 通过 COM 组件访问 Access 文件的更多相关文章

  1. IMAP(Internet Mail Access Protocol,Internet邮件访问协议)以前称作交互邮件访问协议(Interactive Mail Access Protocol)。

    IMAP(Internet Mail Access Protocol,Internet邮件访问协议)以前称作交互邮件访问协议(Interactive Mail Access Protocol).IMA ...

  2. Unity访问Access数据库

    首先,准备工作: 创建一个Access 数据库,命名AccessTest.accdb,添加一些数据用于测试 准备System.Data.dll与System.EnterpriseServices.dl ...

  3. [转载]Unity3D 访问Access数据库

    在开始这个小教程之前呢,其实在网上你已经可以找到相关的资料了,但是我还是要把我自己做练习的一点东西分享出来.写这个教程的主要原因呢,是一个朋友在u3d的官网论坛里,找到了这个demo,但是在他使用的过 ...

  4. 如何使用.net访问Access数据库 (转)

    前言:今天整理程序,看到之前写的一个Demo,也不知道是从哪里参考的了,写到这里,留作备用吧. 使用.net访问Access数据库:1.BL层:新增一个DataAccess类. Code].Defau ...

  5. C#.NET ORM 如何访问 Access 数据库 [FreeSql]

    最近很多 .net QQ 群无故被封停,特别是 wpf 群几乎全军覆没.依乐祝的 .net6交流群,晓晨的 .net跨平台交流群,导致很多码友流离失所无家可归,借此机会使用一次召唤术,有需要的请加群: ...

  6. ADO访问Access数据库错误解决心得随笔

    最近在用ADO访问Access数据库的时候出现了一个奇怪的错误,觉得有必要记录下来,和大家分享一下. 环境 win7 x86系统: VS2012编译器: Office2010: Access2000~ ...

  7. 访问Access日期字段

    在使用sql访问Access日期字段,应在变量前后加#,例子: s:=Format(select xueshID,name,times,qukbz,skdate,banji from dianmjil ...

  8. java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] 不能使用 '(未知的)';文件已在使用中

    最近查看程序输入的日志时发现一个java连接Access的程序时不时的抛出: java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driv ...

  9. Excel中使用VBA访问Access数据库

    VBA访问Access数据库 1. 通用自动化语言VBA VBA(Visual Basic For Application)是一种通用自动化语言,它可以使Excel中的常用操作自动化,还可以创建自定义 ...

随机推荐

  1. OstrichNet 简易统计信息收集工具

    Ostrich 是twitter用于监控服务器性能的一个scala库,项目地址https://github.com/twitter/ostrich, 主要功能是收集.展示统计信息, 同时也提供了关闭服 ...

  2. [PHP源码阅读]strlen函数

    文章来自:http://www.hoohack.me/2016/02/22/phps-source-analytics-strlen 我在github有对PHP源码更详细的注解.感兴趣的可以围观一下, ...

  3. 说说SQL Server 网络配置

    打开Sql Server Configuration Manager,里面显示了SQL Server的网络配置,这些到底表示什么含义呢? 图一:MSSQLSERVER的协议 这些配置选项,其实就是为了 ...

  4. php性能优化

    序   很长时间没有写博文了,最近换了工作,长时间加班,根本没有时间做其他事情!今天闲下来了,想一想php性能方面的事情.这也是我2014年的第一篇博文! 推荐阅读:初学者到中级者应该掌握的!   p ...

  5. Azure PowerShell (1) PowerShell入门

    <Windows Azure Platform 系列文章目录> Update: 2016-01-11 笔者文档主要都是用Azure PowerShell 0.x版本来实现的,比如0.98版 ...

  6. Redis 发布订阅用法

    一.发布订阅模型发布订阅其作用是为了减少依赖关系,通常也叫观察者模式.主要是把耦合点单独抽离出来作为第三方,隔离易变化的发送方和接收方. 发送方:只负责向第三方发送消息.(杂志社把读者杂志交给邮局)接 ...

  7. xamarin 手机顶部状态栏

    修改显示xamarin开发的App的手机顶部状态栏, 步骤一:在项目UWP上的“引用”里右键“添加引用”,选择->Universal Windows->Windows Mobile Ext ...

  8. HTML 最简单的tips 怎么支持指定DIV显示提示信息

    <body> <style type="text/css"> a.link{position:relative;} a.link div.tips{ bor ...

  9. c# 文件属性读取操作及文件之间操作

    c# 获取文件最后修改日期代码FileInfo f = new FileInfo(@"c:\1.txt");Console.WriteLine(f.LastWriteTime.To ...

  10. 用电脑给手机安装App

    每一个账号密码只允许同时授权5台电脑,当授权满后还想授权其他的就必须删除以前的授权.