[Access] C# 通过 COM 组件访问 Access 文件
说明:
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 和 C# 类型转换会降低程序执行效率,就比如像 GetTableNames 方法中循环遍历表名,都要花两三秒时间,所以尽量像 object[] dataRow = recordSet.GetRows(); 直接获取其中的所有数据,然后再遍历处理,会极大提高执行效率;
要修改 Access 中的数据时,一定要先 m_Recordset.Edit(); 才会允许你编辑其中的内容;
[Access] C# 通过 COM 组件访问 Access 文件的更多相关文章
- IMAP(Internet Mail Access Protocol,Internet邮件访问协议)以前称作交互邮件访问协议(Interactive Mail Access Protocol)。
IMAP(Internet Mail Access Protocol,Internet邮件访问协议)以前称作交互邮件访问协议(Interactive Mail Access Protocol).IMA ...
- Unity访问Access数据库
首先,准备工作: 创建一个Access 数据库,命名AccessTest.accdb,添加一些数据用于测试 准备System.Data.dll与System.EnterpriseServices.dl ...
- [转载]Unity3D 访问Access数据库
在开始这个小教程之前呢,其实在网上你已经可以找到相关的资料了,但是我还是要把我自己做练习的一点东西分享出来.写这个教程的主要原因呢,是一个朋友在u3d的官网论坛里,找到了这个demo,但是在他使用的过 ...
- 如何使用.net访问Access数据库 (转)
前言:今天整理程序,看到之前写的一个Demo,也不知道是从哪里参考的了,写到这里,留作备用吧. 使用.net访问Access数据库:1.BL层:新增一个DataAccess类. Code].Defau ...
- C#.NET ORM 如何访问 Access 数据库 [FreeSql]
最近很多 .net QQ 群无故被封停,特别是 wpf 群几乎全军覆没.依乐祝的 .net6交流群,晓晨的 .net跨平台交流群,导致很多码友流离失所无家可归,借此机会使用一次召唤术,有需要的请加群: ...
- ADO访问Access数据库错误解决心得随笔
最近在用ADO访问Access数据库的时候出现了一个奇怪的错误,觉得有必要记录下来,和大家分享一下. 环境 win7 x86系统: VS2012编译器: Office2010: Access2000~ ...
- 访问Access日期字段
在使用sql访问Access日期字段,应在变量前后加#,例子: s:=Format(select xueshID,name,times,qukbz,skdate,banji from dianmjil ...
- java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] 不能使用 '(未知的)';文件已在使用中
最近查看程序输入的日志时发现一个java连接Access的程序时不时的抛出: java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driv ...
- Excel中使用VBA访问Access数据库
VBA访问Access数据库 1. 通用自动化语言VBA VBA(Visual Basic For Application)是一种通用自动化语言,它可以使Excel中的常用操作自动化,还可以创建自定义 ...
随机推荐
- Android N 多窗口模式,你需要知道的一切
Android N中最大.最引人注意的变化就是Mutil-window模式.对于一个开发者,我们最关心的就是:Mutil-window模式下怎么配置mutil-window模式.Activity的生命 ...
- 在Visual Studio上开发Node.js程序
[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio ...
- Hibernate 3.3.2 文档翻译 Day01
Hibernate 3.3.2 文档翻译 翻译人:微冷的雨 第一次书写:2015年11月29日 本人呕心沥血之作,请细心阅读领悟! Day01-1.1 项目描述 微冷的雨翻译:例如,我们将要建立一个可 ...
- 如何创建一个AJAX-Enabled WCF Service
原创地址:http://www.cnblogs.com/jfzhu/p/4041638.html 转载请注明出处 前面的文章中介绍过<Step by Step 创建一个WCF Servi ...
- 在SqlServer2008R2中,在一张表上加上insert、update、delete触发器(带游标)
在日常工作中,在SqlServer2008R2中,需要向一张表上加上触发器,监控插入.更新.删除. --一个触发器内三种INSERT,UPDATE,DELETE状态 IF exists(select ...
- 《JS修炼之道》—— 读后总结
本篇是基于<JS修炼之道>的记录性与总结性的文章,这本书从多种框架的角度,讲述了JS开发中的一些实用技巧. 比如Prototype,JQuery,Mootools,YUI,Dojo,Ext ...
- 程序中保存状态的方式之Cookies
程序中保存状态的方式之 Cookies,之前写过一篇关于ViewState的.现在继续总结Cookies方式的 新建的测试页面login <%@ Page Language="C#&q ...
- HTML5_02之视频、音频、Canvas
1.HTML5新特性之视频播放--video: ①例:<video src=""></video> ②video标签默认为300*150的inline-bl ...
- Java_IO流_File类配合使用(其中用到了递归)
第一:Java File类的功能非常强大,利用Java基本上可以对文件进行所有的操作.以下对Java File文件操作以及常用方法进行简单介绍 案例1:遍历出指定目录下的文件夹,并输出文件名 stat ...
- 群福利:百度云管家-本地SVIP
效果 如果不想登录破解版的百度云(防止泄密)==>复制AppSettingApp.dat和users文件夹,这样你就可以免登录了 最稳定版本:https://yunpan.cn/cBTQc9Iu ...