我有一个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的查看器中看到附件的内容)。 为此,我一直关注this answer:基本上,我想阅读附件并将其保存到进程文件夹中的文件中(以后将由另一个功能删除)。
这是我应该执行的方法(根据上表,输入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
(看不到内容,我也不知道为什么)。
如果我打开Access表,我可以看到正在寻找的附件(在这种情况下,我的fileName
是Spot.xml
:
似乎我遗漏了一些明显的东西,但是我无法弄清楚自己在做错什么...任何进一步研究的提示?
答案 0 :(得分:0)
有关VBA中的示例,请参见Microsoft Docs for Field2.SaveToFile method(可轻松转换为C#互操作码)。
主记录集的M_FILE
字段中的子记录集包含一组特定的字段名称。首先,您可以通过遍历字段集合并打印Field2.Name属性来发现这些内容。上面的链接指示至少两个字段名称为FileName
和FileData
。简短的是,循环应该是
while ((!rstAttach.EOF) && (!fileName.Equals(rstAttach.Fields["FileName"].Value, OrdinalIgnoreCase)))
此外,实际保存文件的行应为
Field2 fld = (Field2)rstAttach.Fields["FileData"];
fld.SaveToFile(fileName);
我刚刚注意到,您链接到的另一个答案具有正确的字段名称,因此此代码中实际上没有任何显着差异。因此,该问题和答案仅是该问题的副本。