Заполнение sqldataадаптера данными не работает

#c# #sql #stored-procedures #parameters #sqldataadapter

Вопрос:

У меня есть этот код, запущенный в событии form_load:

         using (SqlConnection sqlConn = new SqlConnection(strConn))
        {
            sqlConn.Open();
            SqlDataAdapter sqlDa = new SqlDataAdapter("pp_sp_MachineAndOp", sqlConn);
            DataTable sqlDt = Helper.ExecuteDataTable("pp_sp_MachineAndOp", new SqlParameter("@MachineAndOpID", 7));
            sqlDa.Fill(sqlDt);
            dgvMachineAndOp.AutoGenerateColumns = false;
            dgvMachineAndOp.DataSource = sqlDt;

            sqlDa.Dispose();
            sqlConn.Close();

        }
 

Я получаю ошибку «Процедура или функция «pp_sp_MachineAndOp» ожидает параметр «@MachineAndOpID», который не был указан». в строке:

                 sqlDa.Fill(sqlDt);
 

Важно отметить, что если я открою визуализатор данных sqlDt во время выполнения, я увижу ожидаемые результаты!

Вот код, стоящий за помощником.Выполнимо:

         public static DataTable ExecuteDataTable(string storedProcedureName, params SqlParameter[] arrParam)
    {
        DataTable dt = new DataTable();

        // Open the connection 
        using (SqlConnection sqlConn = new SqlConnection(strConn))
        {
            try
            {
                sqlConn.Open();
                // Define the command 
                using (SqlCommand sqlCmd = new SqlCommand())
                {
                    sqlCmd.Connection = sqlConn;
                    sqlCmd.CommandType = CommandType.StoredProcedure;
                    sqlCmd.CommandText = storedProcedureName;

                    // Handle the parameters 
                    if (arrParam != null)
                    {
                        foreach (SqlParameter param in arrParam)
                        {
                            sqlCmd.Parameters.Add(param);
                        }
                    }

                    // Define the data adapter and fill the dataset 
                    using (SqlDataAdapter da = new SqlDataAdapter(sqlCmd))
                    {
                        da.Fill(dt);
                    }
                }
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        return dt;
    }
 

Чего мне не хватает?

Комментарии:

1. Helper.ExecuteDataTable это пользовательский код, мы не можем сказать вам, что с ним не так на расстоянии. Я скажу, что это очень подозрительно, что вам нужно упомянуть pp_sp_MachineAndOp дважды, один раз в конструкторе для SqlDataAdapter , а затем еще раз в помощнике. При правильном дизайне не было бы необходимости повторять это. Я подозреваю, что Helper.ExecuteDataTable это предназначено для выполнения всей работы, и вообще нет необходимости привлекать SqlDataAdapter А.

2. Я добавил код за помощником. Выполнимо.

3. Как вы можете видеть, Helper.ExecuteDataTable действительно выполняет всю работу , которую вам sqlDt предстоит выполнить, в комплекте со своей собственной SqlDataAdapter . Почему вы используете свой собственный? Все, что вам нужно, — это DataTable sqlDt = Helper.ExecuteDataTable("pp_sp_MachineAndOp", new SqlParameter("@MachineAndOpID", 7)); и ничего больше.

Ответ №1:

Удалите все, кроме

  DataTable sqlDt = Helper.ExecuteDataTable("pp_sp_MachineAndOp", new SqlParameter("@MachineAndOpID", 7));
dgvMachineAndOp.AutoGenerateColumns = false;
dgvMachineAndOp.DataSource = sqlDt;
 

твой Помощник.ExecuteDataTable делает все. вам не нужно повторять то же самое в своем коде.

Ответ №2:

Я думаю, что ваш вспомогательный класс создает соединение с базой данных, поскольку в вашей таблице данных есть данные.

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

SqlDataAdapter sqlDa = новый SqlDataAdapter();//используйте только это.

Комментарии:

1. Я попробовал это, и теперь я получаю ошибку: «Свойство SelectCommand не было инициализировано перед вызовом «Заполнить». » Я добавлю помощника. Выполнимый код за несколько минут.

Ответ №3:

вы можете использовать нижеприведенную функцию(требуется модификация в соответствии с вашими потребностями):

  public IDataReader ExecuteReader(string spName, object[] parameterValues)
    {
        command = GetCommand();
        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = spName;
        if (parameterValues != null)
        {
            for (int i = 0; i < parameterValues.Length; i  )
            {
                command.Parameters.Add(parameterValues[i]);
            }
        }
        reader = command.ExecuteReader();
        if (parameterValues != null)
            command.Parameters.Clear();
        return reader;
    }