Поле Memo из файла DBF возвращает только несколько символов, используя VFP OLE DB Provider для .NET - PullRequest
0 голосов
/ 15 июня 2019

Я занимаюсь разработкой приложения Winforms, которое считывает информацию из базы данных .DBF. Я использую VFP OLE DB Provider для обычных запросов, и он работает просто отлично.

Но я дошел до того, что мне нужно прочитать изображение, хранящееся в поле Memo. Если я выполняю обычный запрос SELECT, чтобы получить поле, я получаю только строку со значением

Yoya

Который, по моему мнению, является частью метаданных для изображения JPE, но, очевидно, мне не хватает некоторой информации.

Что мне нужно сделать, это извлечь информацию из базы данных и отобразить ее в виде PictureBox в форме.

Это код, который я использую для чтения информации из БД:

public DataTable SendQuery(string query)
{
    try
    {
        Conn = new OleDbConnection
        {
            ConnectionString = "Provider=vfpoledb;Data Source=C:\Data;Extended Properties=dBASE IV;Collating Sequence=machine;"
        };
        Conn.Open();

        OleDbDataAdapter adapter = new OleDbDataAdapter(query, Conn);
        DataSet ds = new DataSet();
        adapter.Fill(ds);
        Conn.Close();
        return ds.Tables[0];
    }
    catch (OleDbException e)
    {
        MessageBox.Show(e.Message + "\nWith error" + e.ErrorCode, "Error de base de datos");
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message, "Error general");
    }
    finally
    {
        Conn.Close(); //Just to be sure
    }
    return null;
}

Как я упоминал ранее, это прекрасно работает при чтении текстов и чисел (даже в поле заметки, в котором я храню большие тексты), но оно просто не работает с этим конкретным изображением в поле заметки.

Как примечание, я уверен, что ни база данных, ни поля не повреждены.

1 Ответ

1 голос
/ 09 июля 2019

По умолчанию памятное поле обрабатывается как строка с OleDb. Однако в C #, в отличие от документации, строка является строкой ASCIIZ. Он не прочитал бы прошлое, увидев символ \ x00. Вы можете преобразовать поле в BLOB-объект и, таким образом, прочитать его как двоичное значение. Вот пример:

Код VFP для создания образцов данных:

CREATE TABLE c:\temp\imageData FREE (id i, ext c(3), filedata m)
INSERT INTO c:\temp\imageData (id, ext, filedata) VALUES (1,'jpg',FILETOSTR('C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\arm64\AccChecker\AccChecker_HelpFiles\image001.jpg'))
INSERT INTO c:\temp\imageData (id, ext, filedata) VALUES (2,'jpg',FILETOSTR('C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\arm64\AccChecker\AccChecker_HelpFiles\image002.jpg'))
INSERT INTO c:\temp\imageData (id, ext, filedata) VALUES (3,'jpg',FILETOSTR('C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\arm64\AccChecker\AccChecker_HelpFiles\image003.jpg'))

Код для чтения из VFP:

void Main()
{
    var table = SendQuery("select id, ext, cast(filedata as blob) as filedata from imageData");

    foreach (DataRow row in table.Rows)
    {
        var bytes = (byte[])row["filedata"];
        var id = (int)row["id"];
        var ext = (string)row["ext"];

        File.WriteAllBytes(Path.Combine(@"c:\temp", $"test_image{id}.{ext.Trim()}"),bytes);
    }
}

public DataTable SendQuery(string query)
{
    string cnStr = @"Provider=vfpoledb;Data Source=C:\Temp;";
    try
    {
        DataTable tbl = new DataTable();
        new OleDbDataAdapter(query, cnStr).Fill(tbl);
        return tbl;
    }
    catch (OleDbException e)
    {
        MessageBox.Show(e.Message + "\nWith error" + e.ErrorCode, "Error de base de datos");
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message, "Error general");
    }
    return null;
}

PS: Вы могли бы использовать Linq и, таким образом, у вас не возникло бы такой проблемы (у Tom Brothers есть драйвер для VFP - Linq To VFP ).

...