[Access] C#通过COM组件访问Access文件

说明:

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 > 0)

 56         {

 57             try

 58             {

 59                 List<string> fieldNames = new List<string>();

 60                 for (int i = 0; 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 = 0; 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);// 1=RecordsetTypeEnum.dbOpenTable

108             int fieldsCount = m_Recordset.Fields.Count;

109             List<string> fieldNames = new List<string>();

110             for (int i = 0; i < fieldsCount; i++)

111             {

112                 fieldNames.Add(m_Recordset.Fields[i].Name);

113             }

114             for (int rowIndex = 0; 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);// 1=RecordsetTypeEnum.dbOpenTable

149             m_Recordset.MoveFirst();

150             for (int rowIndex = 0; 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 }
View Code
 
通过dynamic构建的COM对象,在使用完成后都要手动关闭销毁,比如代码中的m_AccessApp, m_Database, m_Recordset三个对象,否则只是将m_AccessApp关闭清空释放掉,Access进程还是无法关闭,在程序关闭之前,始终都会有一个空白的无法关闭的Access界面;

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

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

你可能感兴趣的:(Access)