说明:

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. 拥抱.NET Core,学习.NET Core的基础知识补遗

    前言 .NET Core的新特性之一就是跨平台,但由于对之前框架的兼容导致编写一个.NET Core类库变得相当复杂,主要体现为相当多的框架目标和支持平台,今天我们就对.NET Core的跨平台特性进 ...

  2. Web Audio介绍

    Web Audio还是一个比较新的JavaScript API,它和HTML5中的<audio>是不同的,简单来说,<audio>标签是为了能在网页中嵌入音频文件,和播放器一样 ...

  3. EDM制作要点

    EDM是Email Direct Marketing的缩写,虽然也是html,但是和我们在网页上使用的html不同,因为安全原因,各大邮箱服务商级邮件客户端都会对邮件内容进行一定程度上的处理,不会按照 ...

  4. 解决记录日志导致VS2013缓慢的问题

    最近VS2013启动时.编译时.显示项目属性速度狂慢,遇到项目多的,显示项目属性时甚至VS挂掉. 把所有的VS插件卸载.甚至重装VS也不见效果. 用ProcessMonitor发现VS一直在Defau ...

  5. Xcode升级 Alcatraz 无法使用

    Alcatraz 主要是可以管理xcode 插件 随着 Xcode 的更新 Alcatraz 有可能无法使用 以下是解决办法: 1,关闭Xcode 2,如果已经安装过 Alcatraz,先卸载掉,然后 ...

  6. 查看html元素绑定的事件与方法的利器

    WEB标准提倡结构.表现和行为相 分离,现在越来越多采用这种表现和行为的方式,但它也为我们开发调试带来一些问题,网页载入一堆JavaScript,,我们很难搞清楚最后在哪些元素的哪个动作绑定了事件,尤 ...

  7. jsp 分页, 判断是第一页,和最后一页.

    <% //页的行数 int pagesize =20; //当前页 int currentPage = 1; try { currentPage = Integer.parseInt(reque ...

  8. linux创建进程fork的方法步骤

    fork创建进程 函数原型如下 #include// 必须引入头文件,使用fork函数的时候,必须包含这个头文件,否则,系统找不到fork函数 pid_t fork(void); //void代表没有 ...

  9. 【Win10 应用开发】从前台应用触发后台任务

    有关后台任务的使用,估计大伙伴们不会陌生,而且老周曾经在某文中也简单讲述过.说到后台任务,老周想到了一个问题:有人问,后台任务一定要独立写到一个Runtime组件中吗,能不能写到主项目的代码中? 老周 ...

  10. javascript运动系列第四篇——抖动

    × 目录 [1]原理介绍 [2]代码实现 [3]实例应用 前面的话 在运动系列中,前面分别介绍了匀速运动.变速运动和曲线运动.下面介绍一种特殊的运动形式——抖动 原理介绍 抖动其实是往复运动的一种特殊 ...