none
Как правильно очистить элемент dataSet? RRS feed

  • Вопрос

  • Здравствуйте,

    И как правильно очистить элемент dataSet, чтобы затем можно было воспользоваться им для чтения и вывода другой таблицы в dataGridView? 

    В цикле, в котором происходит чтение данных, делаю так:

    {

    try {dataSet1.Tables.Remove(dataSet1.Tables[0]); } catch{}

    dataSet1.Tables.Add(SelectedTable_Name);
    dataGridView1.DataSource = dataSet1;
    dataGridView1.DataMember = dataSet1.Tables[0].TableName;

    ...

    adapter = new SqlDataAdapter("SELECT * FROM " + SelectedTable + ";",connection);
    adapter.Fill(dataSet1.Tables[0]);

    }

    И каждый раз значение SelectedTable разное.

    Однако при чтении, в некоторых случаях, выпадает ошибка:

    An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll
    Additional information: Inconvertible type mismatch between SourceColumn 'definition' of Byte[] and the DataColumn 'definition' of String.

    Заранее спасибо!



    29 февраля 2012 г. 5:50

Ответы

  • //очищаем dataSet2
                     try
                     {
                         dataSet2.Tables[0].Clear();
                         dataSet2.Tables.Remove(dataSet2.Tables[0]);
                     }
                     catch (System.IndexOutOfRangeException)
                     {
                     }
                     dataGridView1.Columns.Clear();
     
                    //устанавливаем соединение с БД выбранной таблицы
                     string SelectedTable = Path.GetFileNameWithoutExtension(treeView1.SelectedNode.Text);
                     TreeNode parentSelectedBD = treeView1.SelectedNode.Parent;
                     string SelectedBD = parentSelectedBD.Text;
                     connectionString = @"Data Source=.;" + "Initial Catalog= " + SelectedBD + ";Integrated Security=True";
                     connection = new SqlConnection(connectionString);
     
                    //настраиваем dataset (dataGridView), читаем имя полей
    
      //Выделенная часть лишняя, не надо вручную создавать DataTable, за Вас всё
      //это сделает DataAdapter, он как раз и для этого, чтобы облегчить Вам жизнь.
      //////////////////////////////////////////////////////////
                     /*dataSet2.Tables.Add(SelectedTable);
                     dataGridView1.DataSource = dataSet2;
                     dataGridView1.DataMember = dataSet2.Tables[0].TableName;
                     dataGridView1.Enabled = false;
                     command = new SqlCommand("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + SelectedTable + "';", connection);
                     connection.Open();
                     reader = command.ExecuteReader();
                     ColumnsCount = 0;
                     while (reader.Read())
                     {
                         for (int i = 0; i < reader.FieldCount; i++)
                         {
                             dataSet2.Tables[0].Columns.Add(reader.GetValue(i).ToString());
                             ColumnsCount++;
                         }
                     }
                     reader.Close();
                     connection.Close();*/
     ///////////////////////////////////////////////////////////////
    
                    //заполняем dataSet (dataGridView) данными из БД
                     adapter2 = new SqlDataAdapter("SELECT TOP 10 * FROM " + SelectedTable + ";", connection);
                    try{
     
                     adapter2.Fill(dataSet2.Tables[0]);
                    }
                     catch (System.InvalidOperationException)
                     {
                         System.Windows.Forms.DialogResult dr = MessageBox.Show("Ошибка при чтении таблицы",
                                                                                 "Просмотр таблицы",
                                                                                  MessageBoxButtons.OK,
                                                                                  MessageBoxIcon.Warning,
                                                                                  MessageBoxDefaultButton.Button1);
                     }
                     //А вот тут, привязываем GridView прямо к DataTable
                      dataGridView1.DataSource = dataSet2.Tables[0];

    • Помечено в качестве ответа Abolmasov Dmitry 6 марта 2012 г. 7:58
    1 марта 2012 г. 11:37
    Модератор
  • Почему не можете, можете. Создаёте один dataSet и всё. А потом загружаете те таблицы, которые вам нужны. А перед обновлением, чистите dataSet.

    dataSet.Tables.Clear(); //или все таблицы
    dataSet.Tables.Remove("TableName");//или одну
    dataAdapter.Fill(dataSet); // и заполняете его заново

    • Помечено в качестве ответа Abolmasov Dmitry 6 марта 2012 г. 7:58
    2 марта 2012 г. 8:07
    Модератор

Все ответы

  • Весь DataSet чистится методом dataSet.Clear(). Отдельные таблицы - методом Remove() коллекции, как Вы и написали, но при условии что она не является частью отношения.

    29 февраля 2012 г. 6:16
    Модератор
  • Пробовала, но такое ощущение что поля в таблице остаются, потому что:

    1) в элементе dataGridView1 я вижу поля с предыдущего вывода

    2) выдаёт ошибку, если есть поля с одинаковыми именами в таблицах, которые пытаюсь прочитать:

    An unhandled exception of type 'System.Data.DuplicateNameException' occurred in System.Data.dll


    Additional information: A column named 'name' already belongs to this DataTable.

    29 февраля 2012 г. 6:28
  • Здравсвтвуйте.

    У вас в DataSet точно нет связанных таблиц?

    Попробуйте перед удалинием таблицы выполнить еще

    Tables[0].Constraints.Clear();

    Возможно это поможет.

    Полезный материал по DataSet - http://www.codeproject.com/Articles/6180/A-Practical-Guide-to-NET-DataTables-DataSets-and-D


    Для связи [mail]

    29 февраля 2012 г. 6:59
  • Нет. Но на всякий случай попробовала - не помогает(
    29 февраля 2012 г. 7:12
  • А почему бы просто не создать новый DataSet? Для чего сохраняется старый?

    Для связи [mail]

    29 февраля 2012 г. 7:20
  • Я пока не очень ориентируюсь что будет рациональней, всё время создавать новый или пользоваться старым.

    Скажите, а может ли такая ошибка появляться если что-то не так с самой таблицей базы данных. 

    An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll
    Additional information: Inconvertible type mismatch between SourceColumn 'definition' of Byte[] and the DataColumn 'definition' of String.                  

    Потому что она появляется даже если эта таблица читается первой.

    29 февраля 2012 г. 7:36
  • А можете сказать в чём общая идея работы вашего приложения? Возможно есть другие пути решения. Из того что я понял, как в цикле создаются, удаляются множество таблиц, возникают впечатления нерационального и нецелесообразного использования ресурсов. Хотя, может я не правильно понял и моё мнение ошибочно.


    29 февраля 2012 г. 12:21
    Модератор
  • В приложении в компоненте treeView1 выводятся имена всех БД и таблиц в виде дерева. При кликании мышкой на имя таблицы, таблица (первые её 10 строк) выводится в компоненте dataGridView1. В форме создан компонент dataSet2. В обработке события выбора делаю:

                    //очищаем dataSet2
                    try
                    {
                        dataSet2.Tables[0].Clear();
                        dataSet2.Tables.Remove(dataSet2.Tables[0]);
                    }
                    catch (System.IndexOutOfRangeException)
                    {
                    }
                    dataGridView1.Columns.Clear();

                    //устанавливаем соединение с БД выбранной таблицы
                    string SelectedTable = Path.GetFileNameWithoutExtension(treeView1.SelectedNode.Text);
                    TreeNode parentSelectedBD = treeView1.SelectedNode.Parent;
                    string SelectedBD = parentSelectedBD.Text;
                    connectionString = @"Data Source=.;" + "Initial Catalog= " + SelectedBD + ";Integrated Security=True";
                    connection = new SqlConnection(connectionString);

                    //настраиваем dataset (dataGridView), читаем имя полей
                    dataSet2.Tables.Add(SelectedTable);
                    dataGridView1.DataSource = dataSet2;
                    dataGridView1.DataMember = dataSet2.Tables[0].TableName;
                    dataGridView1.Enabled = false;
                    command = new SqlCommand("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + SelectedTable + "';", connection);
                    connection.Open();
                    reader = command.ExecuteReader();
                    ColumnsCount = 0;
                    while (reader.Read())
                    {
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            dataSet2.Tables[0].Columns.Add(reader.GetValue(i).ToString());
                            ColumnsCount++;
                        }
                    }
                    reader.Close();
                    connection.Close();


                    //заполняем dataSet (dataGridView) данными из БД
                    adapter2 = new SqlDataAdapter("SELECT TOP 10 * FROM " + SelectedTable + ";", connection);
                   try{

                     adapter2.Fill(dataSet2.Tables[0]);
                   }
                    catch (System.InvalidOperationException)
                    {
                        System.Windows.Forms.DialogResult dr = MessageBox.Show("Ошибка при чтении таблицы",
                                                                                "Просмотр таблицы",
                                                                                 MessageBoxButtons.OK,
                                                                                 MessageBoxIcon.Warning,
                                                                                 MessageBoxDefaultButton.Button1);
                    }

    При первом нажатии на имя таблицы, таблица выводится правильно в компоненте dataGridView1, а при повторном - выводятся только не заполненные столбцы, хотя имена столбцов правильные. То есть не происходит выполнение команды adapter2.Fill(dataSet2.Tables[0]);, данные из таблицы БД не читаются. Если выбрать другую таблицу, она, также, сначала выводится правильно, а при всех последующих - пустая.

    Подскажите, пожалуйста, что я делаю не правильно?

    1 марта 2012 г. 7:58
  • Внесла изменения: каждый раз в обработчике события создаю новый экземпляр dataSet (как мне уже советовал Dmitry)

    dataSet1 = new System.Data.DataSet();

    Теперь всё работает корректно. Только всё равно хотелось бы разобраться, что не верно в первом варианте.

    Всем спасибо!!

    1 марта 2012 г. 11:16
  • //очищаем dataSet2
                     try
                     {
                         dataSet2.Tables[0].Clear();
                         dataSet2.Tables.Remove(dataSet2.Tables[0]);
                     }
                     catch (System.IndexOutOfRangeException)
                     {
                     }
                     dataGridView1.Columns.Clear();
     
                    //устанавливаем соединение с БД выбранной таблицы
                     string SelectedTable = Path.GetFileNameWithoutExtension(treeView1.SelectedNode.Text);
                     TreeNode parentSelectedBD = treeView1.SelectedNode.Parent;
                     string SelectedBD = parentSelectedBD.Text;
                     connectionString = @"Data Source=.;" + "Initial Catalog= " + SelectedBD + ";Integrated Security=True";
                     connection = new SqlConnection(connectionString);
     
                    //настраиваем dataset (dataGridView), читаем имя полей
    
      //Выделенная часть лишняя, не надо вручную создавать DataTable, за Вас всё
      //это сделает DataAdapter, он как раз и для этого, чтобы облегчить Вам жизнь.
      //////////////////////////////////////////////////////////
                     /*dataSet2.Tables.Add(SelectedTable);
                     dataGridView1.DataSource = dataSet2;
                     dataGridView1.DataMember = dataSet2.Tables[0].TableName;
                     dataGridView1.Enabled = false;
                     command = new SqlCommand("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + SelectedTable + "';", connection);
                     connection.Open();
                     reader = command.ExecuteReader();
                     ColumnsCount = 0;
                     while (reader.Read())
                     {
                         for (int i = 0; i < reader.FieldCount; i++)
                         {
                             dataSet2.Tables[0].Columns.Add(reader.GetValue(i).ToString());
                             ColumnsCount++;
                         }
                     }
                     reader.Close();
                     connection.Close();*/
     ///////////////////////////////////////////////////////////////
    
                    //заполняем dataSet (dataGridView) данными из БД
                     adapter2 = new SqlDataAdapter("SELECT TOP 10 * FROM " + SelectedTable + ";", connection);
                    try{
     
                     adapter2.Fill(dataSet2.Tables[0]);
                    }
                     catch (System.InvalidOperationException)
                     {
                         System.Windows.Forms.DialogResult dr = MessageBox.Show("Ошибка при чтении таблицы",
                                                                                 "Просмотр таблицы",
                                                                                  MessageBoxButtons.OK,
                                                                                  MessageBoxIcon.Warning,
                                                                                  MessageBoxDefaultButton.Button1);
                     }
                     //А вот тут, привязываем GridView прямо к DataTable
                      dataGridView1.DataSource = dataSet2.Tables[0];

    • Помечено в качестве ответа Abolmasov Dmitry 6 марта 2012 г. 7:58
    1 марта 2012 г. 11:37
    Модератор
  •  

    Да, Вы абсолютно правы, спасибо!

    Но всё же почему нужно каждый раз создавать новый dataSet? Почему я просто не могу изменить в нём таблицу?

    2 марта 2012 г. 6:30
  • Почему не можете, можете. Создаёте один dataSet и всё. А потом загружаете те таблицы, которые вам нужны. А перед обновлением, чистите dataSet.

    dataSet.Tables.Clear(); //или все таблицы
    dataSet.Tables.Remove("TableName");//или одну
    dataAdapter.Fill(dataSet); // и заполняете его заново

    • Помечено в качестве ответа Abolmasov Dmitry 6 марта 2012 г. 7:58
    2 марта 2012 г. 8:07
    Модератор
  • Вот замечательная книжка, которую я в своё время прочёл, очень полезная и очень подробно всё изложено. Хотя и старовата, скоро на дворе уже .NET 4.5, но вполне актуальная.
    2 марта 2012 г. 8:12
    Модератор