c# - 从 Access DB 读取附件:在此集合中找不到项目
问题描述
我有一个 Access 数据库 ( @"Provider=Microsoft.ACE.OLEDB.12.0
),其中包含一个名为FTLH_DBF
. 该表的结构如下:
+----+--------+--------+--------+--------------------------+
| ID | M_TYPE | M_NAME | M_DESC | M_FILE |
+----+--------+--------+--------+--------------------------+
| 1 | 0 | Spot | Blabla | (Attachment: Spot.xml) |
| 2 | 1 | Hedge | Blabla | (Attachment: Hedge.xml) |
| 3 | 2 | Unwind | Blabla | (Attachment: Unwind.xml) |
+----+--------+--------+--------+--------------------------+
按照设计,代码确保附件名称M_FILE
等于M_NAME
+ .xml
,并且在表中找不到重复项M_NAME
。
我正在尝试在保存附件后重新读取附件(成功地,我可以在 Access 的查看器中看到附件的内容)。为了做到这一点,我一直在关注这个答案:基本上我想阅读附件并将其保存到进程文件夹中的文件中(稍后将被另一个函数删除)。
这是我应该这样做的方法(templateName
根据上表,输入将是Spot
, Hedge
, Unwind
...):
public void dumpAttachmentToFile(string templateName)
{
string fileName = templateName + ".xml";
var dbe = new DBEngine();
Microsoft.Office.Interop.Access.Dao.Database db = dbe.OpenDatabase(DB_LOCATION);
Recordset rstMain = db.OpenRecordset(
"select M_FILE from FTLH_DBF where M_NAME = '" + templateName + "';",
RecordsetTypeEnum.dbOpenSnapshot);
Recordset2 rstAttach = rstMain.Fields["M_FILE"].Value;
while ((!fileName.Equals(rstAttach.Fields["M_FILE"].Value)) && (!rstAttach.EOF))
{
rstAttach.MoveNext();
}
if (rstAttach.EOF)
{
Console.WriteLine("Not found.");
}
else
{
Field2 fld = (Field2)rstAttach.Fields["M_FILE"];
fld.SaveToFile(fileName);
}
db.Close();
}
当我执行此代码时,我收到以下运行时错误:
System.Runtime.InteropServices.COMException
HResult=0x800A0CC1
Message=Item not found in this collection.
Source=MxML-Factory
StackTrace:
at Microsoft.Office.Interop.Access.Dao.Fields.get_Item(Object Item)
at MxML_Factory.Database.DBConnection.dumpAttachmentToFile(String templateName) in C:\Users\Matteo\source\repos\MxML-Factory\MxML-Factory\Database\DBConnection.cs:line 182
at MxML_Factory.Business.MxML.Load(String m_name) in C:\Users\Matteo\source\repos\MxML-Factory\MxML-Factory\Business\MxML.cs:line 73
at MxML_Factory.Utils.BrowseClassMapper.OpenFormInstance(Object TriggerClass, String loadingKey, DatabaseBrowse callback) in C:\Users\Matteo\source\repos\MxML-Factory\MxML-Factory\Utils\BrowseClassMapper.cs:line 24
at MxML_Factory.WinForms.DatabaseBrowse.OpenInstance(String objectKey) in C:\Users\Matteo\source\repos\MxML-Factory\MxML-Factory\WinForms\DatabaseBrowse.cs:line 66
at MxML_Factory.WinForms.DatabaseBrowse.HandleKeyPress(Object sender, KeyEventArgs e) in C:\Users\Matteo\source\repos\MxML-Factory\MxML-Factory\WinForms\DatabaseBrowse.cs:line 91
[...previous calls of the stack which cannot be guilty...]
...在以下代码行:
while ((!fileName.Equals(rstAttach.Fields["M_FILE"].Value)) && (!rstAttach.EOF))
该对象rstAttach
包含一个集合Fields
,但我只能在其中看到一个属性count = 6
(看不到内容,我不知道为什么)。
如果我打开我的访问表,我可以看到有我正在寻找的附件(在这种情况下,我fileName
的是Spot.xml
:
似乎我遗漏了一些明显的东西,但我无法弄清楚我做错了什么......有什么提示可以进一步调查吗?
解决方案
有关VBA 中的示例(可轻松转换为 C# 互操作代码),请参阅Microsoft Docs for Field2.SaveToFile 方法。
主记录集的字段中的子记录M_FILE
集包含一组特定的字段名称。首先,您可以通过遍历字段集合并打印 Field2.Name 属性来发现这些。上面的链接表明至少有 2 个字段名称是FileName
和FileData
。缺点是循环应该是
while ((!rstAttach.EOF) && (!fileName.Equals(rstAttach.Fields["FileName"].Value, OrdinalIgnoreCase)))
此外,实际保存文件的行应该是
Field2 fld = (Field2)rstAttach.Fields["FileData"];
fld.SaveToFile(fileName);
我刚刚注意到您链接到的另一个答案具有正确的字段名称,因此此代码实际上没有什么明显不同。因此,这个问题和答案只是该问题的重复。
推荐阅读
- c - 如何使用指向字符数组的指针一次访问一个数组元素?
- python - 安装 Anaconda 后 CPU 100%
- ios - 模拟器与真实手机中的内容变化
- mysql - 如果列包含重复数据 SQL 则删除行
- javascript - 如何从反应原生中删除应用栏?
- hive - 多个 Tableau 用户连接到 Hive LLAP
- r - 如何根据与其他列中的值匹配的行中的值创建新列?
- wordpress - 如何在 WordPress 网站上使用我自己的语言来发布帖子、标题、菜单栏、链接和其他内容?
- python - 这个散列函数的输入可以根据输出计算吗?
- ios - NSManagedObject 和 Codable 用于存储在服务器和本地存储中的类