none
Отображение значений из связных таблиц RRS feed

  • Общие обсуждения

  • Приветствую.

    Есть две таблицы: user и department. Связь - Relation only. Скриншот ниже.

    На форме есть dataGridview, который выводит отображение таблицы department. Привязан dataGridView через bindingSource. Выглядит так:

    Код для вывода у меня такой:

            //Departments catalog
            private void DepartmentCatalogView()
            {
                catalogGridView.DataSource = departmentBindingSource;
                Text = @"Подразделения";
                catalogGridView.AutoGenerateColumns = false;
                catalogGridView.Columns[0].Visible = false;
                catalogGridView.Columns[1].HeaderText = @"Подразделение";
                catalogGridView.Columns[2].HeaderText = @"Автор записи";
                catalogGridView.Columns[3].HeaderText = @"Дата записи";
            }

    Подскажите, пожалуйста, как сделать так, чтобы вместо user_id отображалось имя этого пользователя из связной таблицы user? Находил какие-то примеры, но не удалось воспроизвести.

    Заранее большое спасибо.

    19 июня 2014 г. 6:07

Все ответы

  • Посмотрите здесь.
    27 июня 2014 г. 13:21
  • Приветствую.

    Спасибо, что обратили внимание на мою проблему. Почитал по ссылке, но все равно ничего не прояснилось.

    Связь, как и показано в моем первом посте, у меня задана в dataDataSet. Я добавил эти строки в метод и вот что получилось:

            //Departments catalog
            private void DepartmentCatalogView()
            {
                departmentBindingSource.DataSource = dataDataSet;
                departmentBindingSource.DataMember = "user_department";
                catalogGridView.DataSource = departmentBindingSource;
                Text = @"Подразделения";
                catalogGridView.AutoGenerateColumns = false;
                catalogGridView.Columns[0].Visible = false;
                catalogGridView.Columns[1].HeaderText = @"Подразделение";
                catalogGridView.Columns[2].HeaderText = @"Автор записи";
                catalogGridView.Columns[3].HeaderText = @"Дата записи";
            }

    Вылетает Exception на DataMember: "Свойство 'user_department' для DataMember не найдено в DataSource." Эта связь точно есть, но как ее получить?

    Спасибо.

    28 июня 2014 г. 10:36
  • Связь, как и показано в моем первом посте, у меня задана в dataDataSet.

    Вылетает Exception на DataMember: "Свойство 'user_department' для DataMember не найдено в DataSource." Эта связь точно есть, но как ее получить?

    У вас задан маппинг? Наподобие:

    dataAdapter.TableMappings.Add("Table2", "LIC_VID");
    

    Далее. После того как задан маппинг, нужно создать дополнительный столбец и добавить его в DataGridView, как в моём примере кода. И задать для этого столбца источник данных к другой таблице - в вашем случае к таблице user. Сам этот источник данных - это другой BindingSource.

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

    28 июня 2014 г. 12:40
  • Спасибо.

    Добавил маппинг и далее:

    departmentTableAdapter.Adapter.TableMappings.Add("user", "user_department");
    
    var textBoxColumn = new DataGridViewTextBoxColumn();
    textBoxColumn.HeaderText = @"Автор записи";
    textBoxColumn.DataGridView.DataSource = userBindingSource;
    textBoxColumn.DataPropertyName = "login";

    На предпоследней строке выпало с эксепшном: Ссылка на объект не указывает на экземпляр объекта.

    И еще, у textBoxColumn нет DisplayMember и DisplayValue. Подскажите, пожалуйста, что не так?


    • Изменено Geokish 29 июня 2014 г. 11:46
    29 июня 2014 г. 8:25
  • Т.е. меня настораживает этот момент:

    textBoxColumn.DataGridView.DataSource

    Ибо напрямую у textBoxColumn тоже нет DataSource.

    29 июня 2014 г. 11:19
  • Добавил маппинг и далее:
    departmentTableAdapter.Adapter.TableMappings.Add("user", "user_department");
    

    По умолчанию, имена таблицам даются Table, Table1, Table2 и т. д. Поэтому нужно использовать либо одно из этих имён (но можно запутаться в циферках), либо дать говорящее название таблице через маппинг. То есть:

    departmentTableAdapter.Adapter.TableMappings.Add("TableN", "user_department");
    

    Где N - номер нужной таблицы. Какой именно - я не могу знать, не видя ваш код.

    ----

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

    Если выложите скрипты создания и наполнения своей БД (как в моём примере по ссылке), чтобы я мог их скопипастить и выполнить у себя, а также приведёте код создания датаадаптеров, который я опять же смогу просто скопировать, то я могу написать код полностью соответствующий задаче.

    Но только ничего лишнего! Краткие скрипты SQL, краткий код C#. Сами понимаете, не хочется продираться через тонны лишнего кода, через бизнес-логику. При этом код должен быть полным, компилирующимся.

    29 июня 2014 г. 13:55
  • Объясните, пожалуйста, что означают эти два параметра в TableMappings: TableN и второй (должно быть название связи между таблицами или что)?

    Как мне узнать НОМЕР нужной таблицы? У меня есть названия таблиц - user и department (скриншот в первом посте).

    Да, при загрузке я видел, что в маппинге есть уже Tableи затем своим кодом добавляется еще одна.

    Подскажите, пожалуйста. Я окончательно запутался.

    Спасибо.

    29 июня 2014 г. 14:22
  • Объясните, пожалуйста, что означают эти два параметра в TableMappings: TableN и второй (должно быть название связи между таблицами или что)?

    В моём примере есть такие строки:

    string strSelect = @"select * from LICENZ; select * from LIC_ORG; select * from LIC_VID";
    
    ...
    
    dataAdapter.SelectCommand = new SqlCommand(strSelect, conn);
    
    ...
    
    dataAdapter.Fill(dataSet);

    Заполняется датасет. В sql-запросе выборка из трёх таблиц. Значит в датасете будут созданы три DataTable. Их имена (свойство TableName) по умолчанию будут Table, Table1, Table2.

    Если не делать маппинг, то дальше в коде пришлось бы использовать именно эти имена. Например:

    licenzSource.DataMember = "Table";

    В итоге код становится менее понятным.

    В данном случае маппинг - это просто переименование таблиц. Пишем:

    dataAdapter.TableMappings.Add("Table", "LICENZ");

    и далее везде используем имя LICENZ, а не безликое Table.

    29 июня 2014 г. 15:38
  • Спасибо за разъяснение.

    В таком случае, мне не нужно создавать маппинг. У меня есть dataSet, который я создал через визард. Соответственно, для каждой таблицы был создан автоматически свой bindingSource и свой tableAdapter.

    При загрузке я заполняю таблицы:

            private void CatalogForm_Load(object sender, EventArgs e)
            { 
            departmentTableAdapter.Fill(dataDataSet.department);
                userTableAdapter.Fill(dataDataSet.user);
            }

    Далее у меня код для вывода в gridView данных из таблицы department:

            private void DepartmentCatalogView()
            {
                var textBoxColumn = new DataGridViewTextBoxColumn
                {
                    HeaderText = @"Автор записи",
                    DataPropertyName = "login",
                    DisplayIndex = 2
                };
    
                catalogGridView.DataSource = departmentBindingSource;
    
                catalogGridView.Columns.Add(textBoxColumn);
                Text = @"Подразделения";
                catalogGridView.AutoGenerateColumns = false;
                catalogGridView.Columns[0].Visible = false;
                catalogGridView.Columns[1].HeaderText = @"Подразделение";
                catalogGridView.Columns[3].HeaderText = @"Дата записи";
            }

    Соответственно, задача продолжает оставаться актуальной. Я не понимаю, что мне нужно сделать. Т.е. я понял алгоритм: создать дополнительную колонку, которую надо будет привязать к userBindingSource и оттуда из таблицы user, для отображения значения, взять столбец login. Но как это реализовать в коде я пока не понимаю.

    Спасибо.


    • Изменено Geokish 29 июня 2014 г. 18:41
    29 июня 2014 г. 16:53
  • Так и не удалось разобраться.

    Помогите, пожалуйста.

    1 июля 2014 г. 16:52
  • Вам нужно в GridView у столбца с внешним ключом (user_id) поменять ColumnType на DataGridViewComboBoxColumn.

    Затем:

    DataPropertyName: user_id

    DataSource: UsersBindingSource

    DisplayMember: Login

    ValueMember: id

    Ну и DisplayStyle у столбца выберите какой нужен.


    У UsersBindingSource - DataSource: dataDataSet, DataMember: user.
    16 июля 2014 г. 18:01
  • Вам нужно в GridView у столбца с внешним ключом (user_id) поменять ColumnType на DataGridViewComboBoxColumn.

    Затем:

    DataPropertyName: user_id

    DataSource: UsersBindingSource

    DisplayMember: Login

    ValueMember: id

    Ну и DisplayStyle у столбца выберите какой нужен.


    У UsersBindingSource - DataSource: dataDataSet, DataMember: user.

    Спасибо большое за помощь. Подскажите, пожалуйста, а как у существующего столбца поменять ColumnType? В дизайнере я его не создавал. Если я программно создаю столбец, то мне тогда надо скрывать столбец user_id.

    Спасибо еще раз.

    21 июля 2014 г. 9:07
  • Не понял насчет "скрывать столбец user_id".

    Вам его не нужно скрывать, я же написал, что с ним нужно сделать:

      var userColumn = new DataGridViewComboBoxColumn
               
    {...}


    P.S.: Вместо var textBoxColumn = new DataGridViewTextBoxColumn.
    21 июля 2014 г. 12:16
  • Не понял насчет "скрывать столбец user_id".

    Вам его не нужно скрывать, я же написал, что с ним нужно сделать:

      var userColumn = new DataGridViewComboBoxColumn
               
    {...}


    P.S.: Вместо var textBoxColumn = new DataGridViewTextBoxColumn.

    Сделал немножко по-другому. В визарде создал необходимые столбцы и там запилил тип.

    Очень благодарен всем, кто помогал. Разобрался с этой темой с вашей помощью. Спасибо!

    21 июля 2014 г. 18:49