说明: 1,采用dynamic调用COM组件,适用于.NET 4.0以上支持dynamic版本的才可以; 2,执行速度不敢恭维,只是因为要用于Silverlight OOB模式中才研究一二; 3,测试环境 .net 4.5 + Silverlight 5.0 + Visual Studio 2013 4,见如下helper类(需引用 using
说明:
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 ///
8 /// 构造函数
9 ///
10 /// Access是否可见
11 public SLAccessHelper( bool visible)
12 {
13 m_AccessApp = AutomationFactory.CreateObject( " Access.Application " );
14 m_AccessApp.Visible = visible;
15 }
16
17 ///
18 /// 打开数据库
19 ///
20 /// Access数据库文件路径
21 /// 是否共享
22 /// 密码
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 ///
30 /// 获取当前数据库中所有表名称集合
31 ///
32 /// 所有表名称集合
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 ///
46 /// 加载表数据
47 ///
48 /// 表名称
49 /// 表数据
50 public List string >> LoadTable( string tableName)
51 {
52 dynamic recordSet = m_Database.OpenRecordset(tableName);
53 int fieldsCount = recordSet.Fields.Count;
54 List string >> data = new List string >> ();
55 if (fieldsCount > 0 )
56 {
57 try
58 {
59 List string > fieldNames = new List string > ();
60 for ( int i = 0 ; 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 )
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 ///
99 /// 添加新纪录
100 ///
101 /// 表格名称
102 /// 数据
103 public void AddNewRecord( string tableName, List 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 )
111 {
112 fieldNames.Add(m_Recordset.Fields[i].Name);
113 }
114 for ( int rowIndex = 0 ; 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 ///
140 /// 更新表格数据
141 ///
142 /// 表格名称
143 /// 数据
144 public void UpdateTable( string tableName, List 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 )
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 ///
177 /// 关闭
178 ///
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(); 才会允许你编辑其中的内容;
查看更多关于C#通过COM组件访问Access文件的详细内容...