Попытка загрузить DataSet, но он всегда нулевой. Обычный sqlReader.GetValue () не является - PullRequest
0 голосов
/ 15 июля 2010

Я мало пользуюсь DataSets. Обычно я использую ORM или просто базовый sqlReader.Read (), за которым следует GetValues ​​(). Я работаю над некоторым унаследованным кодом, который имеет DataSets повсеместно, и во время исправления ошибки пытался высушить некоторые из них.

Однако я не могу загрузить данные в нетипизированный DataSet.

public static DataSet ExecuteStoredProcedure(string storedProcedure, DBEnum db, IEnumerable<SqlParameter> parameters)
{
    DataSet result = new DataSet();
    using (SqlConnection connection = SqlHelper.GetSqlConnection(db))
    {
        SqlCommand command = connection.CreateCommand();
        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = storedProcedure;

        if (parameters != null)
            foreach (SqlParameter parameter in parameters)
                command.Parameters.Add(parameter);

        connection.Open();
        DataTable table = new DataTable();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            table.Load(reader);
        }
        result = table.DataSet; // table.DataSet is always empty!
   }
   return result;
}

Я предположил, что table.Load (reader) делает все необходимые вызовы reader.Read () ... но я продолжил и попробовал это как с, так и без reader.Read () перед таблицей. выгода.

Я знаю, что вызываемая хранимая процедура на самом деле возвращает данные. Если я делаю что-то вроде этого, я вижу данные просто отлично:

using(SqlDataReader reader = command.ExecuteReader())
{
    reader.Read();
    object test = reader.GetValue(0); // returns the expected value
}

Похоже, я здесь упускаю что-то простое, но я уже почесал голову над этим.

Это в .NET 3.5.

Ответы [ 5 ]

2 голосов
/ 15 июля 2010

Если вы можете, я бы предложил использовать SqlDataAdapter для заполнения DataTable

using(SqlDataAdapter sqlDA = new SqlDataAdapter(command))
{
    sqlDA.Fill(table);
}
0 голосов
/ 15 июля 2010

Думайте о наборе данных как о наборе таблиц и, необязательно, информации об отношениях между ними.

В вашем примере кода вы создаете независимую таблицу, которая не принадлежит DataSet.Чтобы прагматично создать таблицу, которая является частью набора данных, вы можете сделать следующее:

DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add();
//or
ds.Tables.Add(MyAlreadyCreatedTable);

Джейсон Эванс, приведенный выше, также корректен, заполнение DataTables и DataSets намного проще, используя SqlDataAdaptors, как он продемонстрировал.

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

Все, что вам нужно сделать, это изменить следующее:

    DataTable table = new DataTable();
    using (SqlDataReader reader = command.ExecuteReader())
    {
        table.Load(reader);
    }

на

//you can skip creating a new DataTable object
using (SqlDataAdapter da = new SqlDataAdapter(command))
{
    da.Fill(result); // the result set you created at the top
}
0 голосов
/ 15 июля 2010

DataSet содержит DataTables, а не наоборот.Поэтому, если вы хотите создать DataSet для возврата, вам, вероятно, захочется создать новый набор данных, а затем добавить в него свой DataTable, прежде чем возвращать его.Если DataTable отсутствует в DataSet, то ссылка на его родительский набор данных всегда будет нулевой.

При этом я также рекомендую предложение Джейсона Эванса использовать SqlDataAdapter.

0 голосов
/ 15 июля 2010

Я считаю, что набор данных должен быть создан первым. Фактически, вы можете использовать DataSet.Load вместо DataTable.Load. DataSet.Load должен создавать таблицы данных, но он не будет работать наоборот.

0 голосов
/ 15 июля 2010

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

...