DataAdapter возвращает пустой набор строк, но DataReader возвращает данные - PullRequest
1 голос
/ 13 октября 2010

Я выполняю запрос, который вызывает SP, этот SP возвращает данные ... но когда я вызываю его с помощью DataAdapter, я не получаю данные результата, если вместо этого использую DataReader ... тогда я получаю данные.База данных - SQL Server, и код использует OleDb по причинам, которые я не могу изменить.

Эти два вызова возвращают разные вещи:

    String commandText = "Declare @return_value int;  exec dbo.copyTemplate ? , ? , ? , ? , ? ,  ? ,   ?, Null , 0 , @return_value;";

    Console.WriteLine("Data Adapter");
    using (OleDbConnection con = new OleDbConnection(connectionString))
    {
        using (OleDbDataAdapter da = new OleDbDataAdapter(commandText, con))
        using (DataTable table = new DataTable("table"))
        {
            da.SelectCommand.Parameters.AddWithValue("?",9).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", "AAAAB").DbType = DbType.String;
            da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", 2).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", true).DbType = DbType.Boolean;
            da.SelectCommand.Parameters.AddWithValue("?", DateTime.Now.Date).DbType = DbType.DateTime;

            da.Fill(table);

            foreach (DataRow dr in table.Rows)
            {
                foreach (DataColumn dc in table.Columns)
                {
                    Console.Write(dr[dc].ToString());
                    Console.Write(" ");
                }
                Console.WriteLine();
            }
        }
    }
    Console.WriteLine("Data Reader");
    using (OleDbConnection con = new OleDbConnection(connectionString))
    {
        using (OleDbCommand cmd = new OleDbCommand(commandText, con))
        {
            cmd.Parameters.AddWithValue("?", 9).DbType = DbType.Int32;
            cmd.Parameters.AddWithValue("?", "AAAAC").DbType = DbType.String;
            cmd.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
            cmd.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
            cmd.Parameters.AddWithValue("?", 2).DbType = DbType.Int32;
            cmd.Parameters.AddWithValue("?", true).DbType = DbType.Boolean;
            cmd.Parameters.AddWithValue("?", DateTime.Now.Date).DbType = DbType.DateTime;

            con.Open();

            using (OleDbDataReader reader = cmd.ExecuteReader())
                while (reader.Read())
                {
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        Console.Write(reader.GetValue(i) ?? "null");
                        Console.Write(" ");
                    }
                    Console.WriteLine();
                }
        }
    }

    Console.ReadKey(true);

Этот код возвращает:

Data Adapter
Data Reader
1057

Я могу вызывать этот код сотни раз, и я всегда получаю значение в Data Reader, а в Data Adapter - ничто, и я могу получить что угодно во втором параметре, это ничего не меняет в результате SP.Я мог бы поменять значения параметров между двумя вызовами или изменить порядок ... и результат был бы таким же: (

Я не понимаю, почему это происходит.

Кто-нибудь знает, в чем может быть проблема?

Приветствия.

ОБНОВЛЕНИЕ : Если я заполняю DataSet вместо DataTable, я получаю результат:

    Console.WriteLine("Data Adapter with DataSet");
    using (OleDbConnection con = new OleDbConnection(connectionString))
    {
        using (OleDbDataAdapter da = new OleDbDataAdapter(commandText, con))
        using (DataSet ds = new DataSet("table"))
        {
            da.SelectCommand.Parameters.AddWithValue("?",9).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", "AAAAB").DbType = DbType.String;
            da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", 2).DbType = DbType.Int32;
            da.SelectCommand.Parameters.AddWithValue("?", true).DbType = DbType.Boolean;
            da.SelectCommand.Parameters.AddWithValue("?", DateTime.Now.Date).DbType = DbType.DateTime;

            da.Fill(ds);

            foreach (DataTable table in ds.Tables)
                foreach (DataRow dr in table.Rows)
                {
                    foreach (DataColumn dc in table.Columns)
                    {
                        Console.Write(dr[dc].ToString());
                        Console.Write(" ");
                    }
                    Console.WriteLine();
                }
        }
    }

Но DataSet содержит только одну таблицу, поэтому я до сих пор не понимаю, почему DataAdapter.Fill (DataTable) не работает.

1 Ответ

2 голосов
/ 14 октября 2010

Проблема в том, что процедура сохранения (как указывало @leppie) возвращает несколько наборов результатов, первый из которых пустой, а второй содержит фактический результат.

DataAdapter.Fill (DataTable) получает толькопервый набор результатов и поместить его в DataTable, так как этот результат пуст, вы получите пустой DataTable.Вы не можете получить значение «ноль», потому что DataTable уже создан, адаптер просто заполняет DataTable.

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

DataAdapter.Fill (DataSet) получает DataTable для каждого набора результатов, поскольку первый равен нулю, а во втором есть только данные, вы получаете DataSet только с одним DataTable.

Правильный и безболезненный способ решить эту проблему - это исправить хранимую процедуру и вернуть только один набор результатов, вероятно, есть что-то, что возвращает пустую переменную или что-то подобное в SP.Если вы хотите поддерживать несколько наборов результатов, вам придется использовать DataAdapter.Fill (DataSet) и справиться с мыслью о том, что, возможно, в заполненном DataSet имеется более одного DataTable.

http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/8fdbaa2d-1f1e-461f-8505-b80ea0c415f2

...