【问题标题】:Reading attached files from database using OLE-DB使用 OLE-DB 从数据库中读取附件
【发布时间】:2012-08-05 19:07:32
【问题描述】:

我正在尝试使用 C# 读取 Microsoft Access 数据库。我正在使用 OLE-DB 类。问题是这段代码

OleDbDataReader reader = Command.ExecuteReader(); 
while (reader.Read())
{
    Console.WriteLine(reader.GetFieldType(0) + "\t" + reader.GetFieldType(1) + "\t" + reader.GetFieldType(2) +
            "\t" + reader.GetFieldType(3) + "\t" + reader.GetFieldType(4) + "\t" + reader.GetFieldType(5));
}

告诉我,第 5 个字段来自数据类型字符串。但它是一个附件。当我试图读取这个字符串时,它是空的。

System.Int32    System.String   System.String   System.Int32    System.DateTime    System.String

有没有办法从数据库中读取附件?

【问题讨论】:

  • 五个字段,我已经添加了控制台的输出。
  • “从数据库中读取附件”是什么意思?
  • 但是您正在尝试阅读 6 个字段。 0 => 5
  • 哦,抱歉有六个字段。
  • 要了解为什么您的代码不起作用,我们需要了解更多关于您的代码、您的 select 子句等...。

标签: c# database ms-access oledb


【解决方案1】:

我知道您要求使用 OleDb,但对于 DAO,您可以这样说:

    DBEngine dbe = new DBEngine();
    Database db = dbe.OpenDatabase(@"z:\docs\test.accdb", false, false, "");
    Recordset rs = db.OpenRecordset("SELECT TheAttachment FROM TheTable", 
        RecordsetTypeEnum.dbOpenDynaset, 0, LockTypeEnum.dbOptimistic);

    Recordset2 rs2 = (Recordset2)rs.Fields["TheAttachment"].Value;

    Field2 f2 = (Field2)rs2.Fields["FileData"];
    f2.SaveToFile(@"z:\docs\ForExample.xls");
    rs2.Close();
    rs.Close();

参考:Programmatically managing Microsoft Access Attachment-typed field with .NET

【讨论】:

    【解决方案2】:

    这有点棘手,但你不能只查询附件列,你只会得到文件名。您必须从附件列中的附件对象中选择值,并拉取字节数组(存储在filedata中),然后删除Access添加到文件中的标题:

    var connection = new OleDbConnection(connectionString);
    connection.Open();
    var dt = new DataTable("Attachments");
    var dataAdapter = new OleDbDataAdapter(@"select attachmentColumn.FileData as filedata, attachmentColumn.FileName as filename, attachmentColumn.FileType as filetype from tablename", connection);
    dataAdapter.Fill(dt);
    
    foreach (DataRow row in dt.Rows)
    {
      var filename = row["filename"].ToString();
      if (string.IsNullOrWhiteSpace(filename)) continue;
      var filedata = (byte[]) row["filedata"];
      int header = (int) filedata[0];
      byte[] actualFile = new byte[filedata.Length - header];
      Buffer.BlockCopy(filedata, header, actualFile, 0, actualFile.Length);
      // do stuff with byte array!
      File.WriteAllBytes("C:\\" + filename, actualFile);
    }
    

    请记住,未压缩的文件将由 Access 压缩。更多关于 here 的信息。 希望这对你有用!

    【讨论】:

    • 我正在使用 DAO,但我提取的文件已损坏...感谢 HEADER 部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多