说明:

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. 跨平台移动开发UI语言 -XAML

    Xamarin.Forms 把XAML (Extensible Application Markup Language, XAML) 带进了ios,android的界面开发,也就使得使用Xamarin ...

  2. SQLite vs MySQL vs PostgreSQL:关系型数据库比较

    自1970年埃德加·科德提出关系模型之后,关系型数据库便开始出现,经过了40多年的演化,如今的关系型数据库种类繁多,功能强大,使用广泛.面对如此之多的关系型数据库,我们应该如何权衡找出适合自己应用场景 ...

  3. JavaScript面向对象之我见

    序言 在JavaScript的大世界里讨论面向对象,都要提到两点:1.JavaScript是一门基于原型的面向对象语言 2.模拟类语言的面向对象方式.对于为什么要模拟类语言的面向对象,我个人认为:某些 ...

  4. Curator Framework的基本使用方法

    Curator Framework提供了简化使用zookeeper更高级的API接口.它包涵很多优秀的特性,主要包括以下三点: 自动连接管理:自动处理zookeeper的连接和重试存在一些潜在的问题: ...

  5. java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required

    java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required 严重: Exceptio ...

  6. 有一个团队协同工具,叫Worktile

    项目管理,本是一个老生常谈的话题,曾几何时大碗云集在这个市场,其中不乏出现像微软.SAP.IBM.用友这样的名字.复杂而又冗繁的流程控制,让人们划分成两类人,一类是会使用这些工具和系统的人,另一类是不 ...

  7. [公告]Senparc.Weixin v4.7.0 升级说明(2016-08-08)

    本次升级包含了除QY以外所有的类库,升级内容包括: 1.重构Conatainer结构,删除 ItemCollection 属性,直接使用ContainerBag加入到缓存: 2.重构IContaine ...

  8. android 获取屏幕宽度和高度

    // 获取屏幕宽高(方法1) int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480p ...

  9. Unity导出的Xcode工程目录

    Classes文件夹: Unity Runtime和ObjectC代码 main.mm和AppController.mm:应用程序入口点 iPhone_Profiler.h:定义了启用内部分析器(In ...

  10. OpenCascade Draw Test Harness

    OpenCascade Draw Test Harness eryar@163.com Abstract. Draw is a command interpreter based on Tcl/Tk ...