Почему MS-доступ odbc возвращает числа, но нет строк в С#?

Я использую ODBC-соединение для извлечения данных из файла Access (.mdb) в среде Unity3D (Mono.net) в Windows 7, и соединение, разбор и запросы происходят без каких-либо ошибок.

Но когда я читаю полученные данные, я получаю только цифры из базы данных. Это могут быть целые числа или числа Float. Но когда я пытаюсь извлечь строку, она всегда возвращает пустую строку.

Вот что я использую в своем классе DataBaseHandler для выполнения запросов (выписок):

public ArrayList Execute(string req)
{
ArrayList output = new ArrayList();

[...]

cmd = new OdbcCommand(req);
cmd.Connection = accessConnection;

OdbcDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
    String[] row = new String[reader.FieldCount];

    for (int i=0; i<reader.FieldCount; i++) {
        if (!reader.IsDBNull(i)) { // Added if for Visual Studio
            // Getting empties strings, but work fine with numbers
            row[i] = reader.GetValue(i).ToString(); 
            // I was using GetString before, but didn't work with Visual Studio
        }
    }

    output.Add( row );
}

[...]
return output;
}

И это то, что я выполняю для проверки запроса:

ArrayList data = db.Execute("SELECT * FROM Materials");

foreach (String[] row in data) {
    string line = "";
    foreach (String s in row) {
        line += s + " - ";
    }
    Debug.Log(line); // Logging in Unity3D console
}

И я получаю:

1234 - 23.1 - - -
5678 - 12.9 - - -

Вместо:

1234 - 23.1 - A string - Another string -
5678 - 12.9 - Hello - World -

Почему я получаю только числа и строки, и как я могу их исправить?

EDIT: он отлично работает с Visual Studio 12 и Windows 7, и изменения, которые я должен был сделать для работы с Visual Studio, не показали улучшения в моей программе Unity.

Ответы

Ответ 1

Я должен начать с того, что у меня нет среды для воспроизведения этого; мой ответ очень основан на том, что я потратил на С# на Windows с SQL Server; а именно, что буферы, используемые под DataReader, повторно используются для эффективности памяти.

Когда числа преобразуются в строки, память должна быть выделена для строки, так как в настоящее время строка не существует. Когда ToString запускается в реальной строке, вы, вероятно, получаете ссылку на строку, все еще погруженную глубоко в DataReader. Затем эта память будет повторно использована следующей записью.

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

Ответ 2

Я думаю, что вы используете DataSet вместо DataReader. При чтении данных из баз данных Access!

Ответ 3

существует несколько неправильных методов кодирования [string line = ""; строка string = String.Empty;] там

Вывести все строку перед вторым оператором foreach. вы видите свою проблему

Ответ 4

Вам нужно использовать метод GetString (columnOrdinal), где columnOrdinal - столбец нулевой строки.

Вам нужно указать тип столбцов, возвращаемых при использовании ODBC. Так что в вашем случае это будет.

public ArrayList Execute(string req)
{
ArrayList output = new ArrayList();

[...]

cmd = new OdbcCommand(req);
cmd.Connection = accessConnection;

OdbcDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
    String[] row = new String[reader.FieldCount];

    for (int i=0; i<reader.FieldCount; i++) {
        if (!reader.IsDBNull(i)) { // Added if for Visual Studio

            if (i > 0 && i < 2)
            {
                row[i] = reader.GetInt32(i);
            }
            else
            {
                row[i] = reader.GetString(i);
            }
        }
    }

    output.Add( row );
}

[...]
return output;
}

В противном случае Я верю GetValue возвращает нулевой объект.