说明:

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;):
 public class SLAccessHelper
{
private dynamic m_AccessApp;// Access.Application
private dynamic m_Database;// Database
private dynamic m_Recordset; /// <summary>
/// 构造函数
/// </summary>
/// <param name="visible">Access是否可见</param>
public SLAccessHelper(bool visible)
{
m_AccessApp = AutomationFactory.CreateObject("Access.Application");
m_AccessApp.Visible = visible;
} /// <summary>
/// 打开数据库
/// </summary>
/// <param name="filePath">Access数据库文件路径</param>
/// <param name="exclusive">是否共享</param>
/// <param name="bstrPassword">密码</param>
public void OpenDb(string filePath, bool exclusive = false, string bstrPassword = "")
{
m_AccessApp.OpenCurrentDatabase(filePath, exclusive, bstrPassword);
m_Database = m_AccessApp.CurrentDb();
} /// <summary>
/// 获取当前数据库中所有表名称集合
/// </summary>
/// <returns>所有表名称集合</returns>
public List<string> GetTableNames()
{
List<string> tableNames = new List<string>();
dynamic tableDefs = m_Database.TableDefs;
foreach (dynamic tableDef in tableDefs)
{
tableNames.Add(tableDef.Name);
} return tableNames;
} /// <summary>
/// 加载表数据
/// </summary>
/// <param name="tableName">表名称</param>
/// <returns>表数据</returns>
public List<List<string>> LoadTable(string tableName)
{
dynamic recordSet = m_Database.OpenRecordset(tableName);
int fieldsCount = recordSet.Fields.Count;
List<List<string>> data = new List<List<string>>();
if (fieldsCount > )
{
try
{
List<string> fieldNames = new List<string>();
for (int i = ; i < fieldsCount; i++)
{
fieldNames.Add(recordSet.Fields[i].Name);
}
data.Add(fieldNames);
if (!recordSet.EOF)
{
recordSet.MoveFirst();
while (!recordSet.EOF)
{
object[] dataRow = recordSet.GetRows();// 返回一维数组
List<string> dataRowStr = new List<string>();
for (int i = ; i < dataRow.Length; i++)
{
dataRowStr.Add(dataRow[i] == null ? "" : dataRow[i].ToString());
}
data.Add(dataRowStr);
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (recordSet != null)
{
recordSet.Close();
((IDisposable)recordSet).Dispose();
recordSet = null;
}
}
} return data;
} /// <summary>
/// 添加新纪录
/// </summary>
/// <param name="tableName">表格名称</param>
/// <param name="data">数据</param>
public void AddNewRecord(string tableName, List<Dictionary<string, object>> data)
{
try
{
m_Recordset = m_Database.OpenRecordset(tableName, );// 1=RecordsetTypeEnum.dbOpenTable
int fieldsCount = m_Recordset.Fields.Count;
List<string> fieldNames = new List<string>();
for (int i = ; i < fieldsCount; i++)
{
fieldNames.Add(m_Recordset.Fields[i].Name);
}
for (int rowIndex = ; rowIndex < data.Count; rowIndex++)
{
m_Recordset.AddNew();
foreach (string fieldName in fieldNames)
{
m_Recordset.Fields[fieldName].Value = data[rowIndex][fieldName];
}
m_Recordset.Update();
}
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (m_Recordset != null)
{
m_Recordset.Close();
((IDisposable)m_Recordset).Dispose();
m_Recordset = null;
}
}
} /// <summary>
/// 更新表格数据
/// </summary>
/// <param name="tableName">表格名称</param>
/// <param name="data">数据</param>
public void UpdateTable(string tableName, List<Dictionary<string, string>> data)
{
try
{
m_Recordset = m_Database.OpenRecordset(tableName, );// 1=RecordsetTypeEnum.dbOpenTable
m_Recordset.MoveFirst();
for (int rowIndex = ; rowIndex < data.Count; rowIndex++)
{
m_Recordset.Edit();
foreach (string fieldName in data[rowIndex].Keys)
{
m_Recordset.Fields[fieldName].Value = data[rowIndex][fieldName];
}
m_Recordset.Update();
m_Recordset.MoveNext();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (m_Recordset != null)
{
m_Recordset.Close();
((IDisposable)m_Recordset).Dispose();
m_Recordset = null;
}
}
} /// <summary>
/// 关闭
/// </summary>
public void Close()
{
if (m_Database != null)
{
m_Database.Close();
((IDisposable)m_Database).Dispose();
m_Database = null;
}
if (m_AccessApp != null)
{
m_AccessApp.CloseCurrentDatabase();
// m_AccessApp.Quit();// 导致最后会弹出Access主页面
((IDisposable)m_AccessApp).Dispose();
m_AccessApp = null;
}
GC.Collect();
}
}
 
通过 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. 分享基于Entity Framework的Repository模式设计(附源码)

    关于Repository模式,在这篇文章中有介绍,Entity Framework返回IEnumerable还是IQueryable? 这篇文章介绍的是使用Entity Framework实现的Rep ...

  2. 操作系统核心原理-7.设备管理:I/O原理

    一.I/O的基本知识 1.1 为何要有I/O 前面阐述了操作系统具有进程管理.内存管理.外存管理三大核心功能,但是计算机归根是为人类服务的,这就要求计算机必须提供某种机制使得人们可以向计算机发出命令或 ...

  3. Web3DGame之路,Babylonjs 和TypeScript学习笔记(一)

    一个开源的Webgl3D引擎,javascript or typescript http://www.babylonjs.com 啥是WebGL WebGL 网页图形库,简称WebGL,是一个JS库, ...

  4. 3dmax模型制作备忘录

    md2导出: http://thegreystudios.com/blog/?p=278 http://wenku.baidu.com/view/4d5652e2524de518964b7d89.ht ...

  5. 浅谈android中的目录结构

    之前在android游戏开发中就遇到本地数据存储的问题:一般情形之下就将动态数据写入SD中存储,在没有SD卡的手机上就需另作处理了;再有在开发android应用的过程中,总要去调试APP,安装时又想去 ...

  6. iOS-中app启动闪退的原因

    这种情况应和所谓的内存不足关系不大,很少有程序会在初始化时载入大量内容导致崩溃,并且这类问题也很容易在开发阶段被发现,所以内存不足造成秒退的可能性低(内存不足退,通常是程序用了一段时间,切换了几个画面 ...

  7. iOS-Objective-C基础

    一.Foundation框架 概述 我们前面的章节中就一直新建Cocoa Class,那么Cocoa到底是什么,它和我们前面以及后面要讲的内容到底有什么关系呢?Objective-C开发中经常用到NS ...

  8. junit测试,使用classpath和file 加载文件的区别

    用junit测试发现一个问题,怎么加载配置文件?一直都出现这样的错误 ERROR: org.springframework.test.context.TestContextManager - Caug ...

  9. 《JS设计模式笔记》 2,简单工厂模式

    <script type="text/javascript"> //简单工厂模式 //定义:由一个方法来决定到底要创建哪个类的实例,而这些实例经常拥有相同的接口.其实例 ...

  10. 【资源】108个大数据文档PDF开放下载-整理后打包下载

                  本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html        本博客其他.NET开源项目文章目录:h ...