C # Заполнить форму после поиска в двух связанных таблицах

Добрый день. Я пытался решить эту проблему в течение некоторого времени, и я не могу ее решить, (я объясняю себе, это может быть немного долго.)

Я делаю форму, которая показывает записи таблицы (компонентов), и к этому добавляются записи второй стол (поставщики). Оба связаны так, что форма, которая заполняется из таблицы компонентов, может заполнять поля поставщика. То есть:

introducir la descripción de la imagen aquí

Форма показывает:

  1. Список с именами компонентов, при выполнении Нажатие на имя загрузит полные данные в оставшуюся часть формы.
  2. Текстовое поле для полей в таблице компонентов, для этого примера имя_компонента.
  3. Текстовое поле для полей в таблице поставщиков, которые должны заполняться автоматически, так как они связаны с компонентами. Для этого примера имя_поставщика.

introducir la descripción de la imagen aquí

Пока все хорошо, работает как надо.

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

Однако в случае необходимости загрузки связанных данных из другой таблицы это больше не работает, потому что экземпляры DataTables не имеют исходных отношений DataSet. Создается одна таблица с обоими результатами:

            else
        {
            // Búsqueda general cuando no se cumplen las anteriores condiciones
            OdbcDataAdapter sdata = new OdbcDataAdapter("SELECT componentes.*,nombre_empresa FROM proveedores INNER JOIN componentes ON proveedores.id = id_prov_comp WHERE nombre_empresa ILIKE '%" + buscar + "%' OR nombre_componente ILIKE '%" + buscar + "%' OR referencia ILIKE '%" + buscar + "%' OR peso_uni ILIKE '%" + buscar + "%' OR codigo_barras ILIKE '%" + buscar + "%' OR fecha_ult_precio ILIKE '%" + buscar + "%'", conn);

            DataTable dtbl = new DataTable();

            sdata.Fill(dtbl);


            componentesBindingSource.DataSource = dtbl;


        }

        //resetea el campo de busqueda y lo deja listo para la proxima busqueda.

        textBox_comp_consulta_buscar.Text = null;

И при попытке заполнить данные формы поле поставщика теряет свою связь и не изменяется при выборе другого компонента, так как данные берутся из нового. объединенная таблица экземпляров (INNER JOIN), а не исходных связанных таблиц.

Так как я не мог это исправить, я подумал о создании экземпляра DataClet .Clone () и работе над ним, но я не могу создать его в операторе if / else.

Итак, прямо сейчас я создаю экземпляры DataSet, DataTables, их Первичных ключей и их отношений непосредственно в инструкции ELSE. Прямо сейчас код выглядит следующим образом:

            else
        {
            // Busqueda general cuando no se cumplen las anteriores condiciones

            //OdbcDataAdapter sdata = new OdbcDataAdapter("SELECT componentes.*,proveedores.id,nombre_empresa FROM proveedores INNER JOIN componentes ON proveedores.id = id_prov_comp WHERE nombre_empresa ILIKE '%" + buscar + "%' OR nombre_componente ILIKE '%" + buscar + "%' OR referencia ILIKE '%" + buscar + "%' OR peso_uni ILIKE '%" + buscar + "%' OR codigo_barras ILIKE '%" + buscar + "%' OR fecha_ult_precio ILIKE '%" + buscar + "%'", conn);
            OdbcDataAdapter sdata = new OdbcDataAdapter("SELECT * FROM componentes WHERE nombre_componente ILIKE '%" + buscar + "%'", conn);
            OdbcDataAdapter sdata2 = new OdbcDataAdapter("SELECT * FROM proveedores WHERE nombre_empresa ILIKE '%" + buscar + "%'", conn);

            DataSet ds = new DataSet();

            DataTable dtbl = new DataTable("dtbl");
            DataTable dtbl2 = new DataTable("dtbl2");

                sdata.Fill(dtbl);
                sdata2.Fill(dtbl2);

                ds.Tables.Add(dtbl);
                ds.Tables.Add(dtbl2);

            dtbl.PrimaryKey = new DataColumn[] { dtbl.Columns["id"] };
            dtbl2.PrimaryKey = new DataColumn[] { dtbl2.Columns["id"] };

            DataRelation dr = new DataRelation("provcomp",
                ds.Tables["dtbl2"].Columns["id"],
                ds.Tables["dtbl"].Columns["id_prov_comp"]);

            ds.Relations.Add(dr);
            ds.AcceptChanges();

            proveedoresBindingSource1.DataSource = dtbl2;
            componentesBindingSource.DataSource = dtbl;
        }

Из этого кода я получаю два поведения:

  1. Первое, если поиск - это термины, присутствующие в таблице компонентов (dtbl), из строки ds.Relations.Add (dr); Я получу ошибку: «Это ограничение не может быть включено, поскольку все значения не имеют соответствующих первичных значений.»
  2. Однако, если поиск представляет собой термин, присутствующий в таблице поставщиков (dtbl2), ошибки не возникает, и форма загружается пустой, за исключением поля поставщика.

Ну, вот я застряла, как я могу получить то, что пытаюсь, я сделала что-то не так? Или каким-то другим способом? Я ходил по Интернету в течение нескольких дней безуспешно.

0
задан 15.06.2017, 21:13
1 ответ

Проблема заканчивает, сделав одну bГєsqueda на данных и тем, что показывает результат на этом же самом контроле. Делать это на простой пластине функционирует верно, просто опрокидывая результат QUERY в инстанцию datatable и потом меняя Datasource в эту инстанцию. Это функционирует.

Вместо того, чтобы использовать этот mГ©todo, ты propngo использование класса DataView , посредством его собственности RowFilter.

Следующий пример значится:

  • 2 DataGridViews, один для главной пластины и другого для второстепенной.
  • 1 TextBox, чтобы вводить , пойдите из поставщика разыскивать.
  • 1 Button, чтобы начинать ее bГєsqueda.

    Public Class Form1
    
        Dim MiDataSet As DataSet = New DataSet
        Dim dvDetalles As DataView
    
        Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
            ' Valores experimentales para la tabla primaria '
            Dim dtPrimaria_Proveedores As DataTable = New DataTable("Proveedores")
            With dtPrimaria_Proveedores.Columns
                .Add("id")
                .Add("nombre_empresa")
                .Add("cif_nif")
            End With
            With dtPrimaria_Proveedores.Rows
                .Add("1", "Electrónica Jujuy", "1234567890")
                .Add("2", "Helados Misiones", "2345678901")
                .Add("3", "Sistemas Neuquén", "3456789012")
                .Add("4", "Gaseosas Entre Ríos", "4567890123")
            End With
    
            ' Valores experimentales para la tabla secundaria '
            Dim dtSecundaria_Componentes As DataTable = New DataTable("Componentes")
            With dtSecundaria_Componentes.Columns
                .Add("id")
                .Add("nombre_componente")
                .Add("referencia")
                .Add("id_proveedor")
            End With
            With dtSecundaria_Componentes.Rows
                .Add("1", "Resistencia 1k", "1E1", "1")
                .Add("2", "Cucurucho", "2H2", "2")
                .Add("3", "Compresor de video", "3S3", "3")
                .Add("4", "Lima limón 1L", "4G4", "4")
                .Add("5", "Frutas rojas", "5H5", "2")
                .Add("6", "Editor Binario", "4S4", "3")
                .Add("7", "Guayaba Mango 3L", "1G1", "4")
                .Add("8", "Diseñador UML", "2S2", "3")
            End With
    
            ' Agrega las tablas al DataSet '
            MiDataSet.Tables.Add(dtPrimaria_Proveedores)
            MiDataSet.Tables.Add(dtSecundaria_Componentes)
    
            ' Crea la relación '
            MiDataSet.Relations.Add("proveedores_componentes", _
            MiDataSet.Tables("Proveedores").Columns("id"), _
            MiDataSet.Tables("Componentes").Columns("id_proveedor"))
    
            ' Establece los enlazadores '
            Dim PrimariaBindingSource As New BindingSource
            Dim SecundariaBindingSource As New BindingSource
    
            PrimariaBindingSource.DataMember = "Proveedores"
            PrimariaBindingSource.DataSource = MiDataSet
    
            SecundariaBindingSource.DataMember = "proveedores_componentes"
            SecundariaBindingSource.DataSource = PrimariaBindingSource
    
            ' Asigna el origen de datos para los DataGridViews '
            Me.DataGridView1.DataSource = PrimariaBindingSource
            Me.DataGridView2.DataSource = SecundariaBindingSource
    
            ' Pide una vista de la tabla secundaria para realizar las búsquedas '
            dvDetalles = MiDataSet.Tables("Componentes").DefaultView
        End Sub
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            ' La propiedad RowFilter permite filtrar las filas '
            dvDetalles.RowFilter = "id_proveedor=" & Me.TextBox1.Text
    
            ' El resultado del filtro se muestra en el DataGridView2 '
            Me.DataGridView2.DataSource = dvDetalles
        End Sub
    End Class
    

Соединения Гєtiles:


2ВЄ EDICIГ “N

Другая форма, чтобы просачиваться, - используя собственность Filter из BindingSource.

В следующем примере подмостки - те же самые, что те cГіdigo предыдущий, с теми же линиями. UsГ© Access , потому что у меня нет PostgreSQL .

Контроль - один ListBox, который заносит в список имена компонентов, один TextBox для каждого поля, и одного TextBox, чтобы разыскивать.

Она bГєsqueda осуществляется по мере того, как пользователь кладет текст. Она actualizaciГіn контроля он automГЎtica.

        private DataSet ds = new DataSet("BD");
        private BindingSource bs_ProveedoresComponentes;

        private void Form1_Load(object sender, EventArgs e)
    {        
        System.Data.OleDb.OleDbDataAdapter da_Componentes = new System.Data.OleDb.OleDbDataAdapter("SELECT c.id as id_componente, nombre_componente, referencia, id_proveedor, nombre_empresa, cif_nif FROM Componentes c INNER JOIN Proveedores p ON c.id_proveedor = p.id", cn);

        // Se llena ds con el INNER JOIN entre las tablas Proveedores-Componentes.
        da_Componentes.Fill(ds, "Proveedores-Componentes");

        // Se crea el enlace para la tabla INNER JOIN.
        bs_ProveedoresComponentes = new BindingSource(ds, "Proveedores-Componentes");

        // Se enlazan todos los controles.
        this.ListBox1.DataSource = bs_ProveedoresComponentes;
        this.ListBox1.DisplayMember = "nombre_componente";

        this.txt_componente_id.               DataBindings.Add("Text", bs_ProveedoresComponentes, "id_componente");
        this.txt_componente_nombre_componente.DataBindings.Add("Text", bs_ProveedoresComponentes, "nombre_componente");
        this.txt_componente_referencia.       DataBindings.Add("Text", bs_ProveedoresComponentes, "referencia");
        this.txt_componente_id_proveedor.     DataBindings.Add("Text", bs_ProveedoresComponentes, "id_proveedor");

        this.txt_proveedor_id.            DataBindings.Add("Text", bs_ProveedoresComponentes, "id_proveedor");
        this.txt_proveedor_nombre_empresa.DataBindings.Add("Text", bs_ProveedoresComponentes, "nombre_empresa");
        this.txt_proveedor_cif_nif.       DataBindings.Add("Text", bs_ProveedoresComponentes, "cif_nif");       
    }

    private void txtBuscar_TextChanged(object sender, EventArgs e)
    {
        string buscar = this.txtBuscar.Text.Trim();
        bs_ProveedoresComponentes.Filter = "nombre_empresa LIKE '%" + buscar + "%'";
    }

Другая opciГіn: , чтобы использовать индивидуальные подмостки, без INNER JOIN, возможно использовать WHERE, но necesitarГЎ parГЎmetro id:

SELECT * FROM Proveedores WHERE id = paramid

И это requerirГЎ, что кодифицировал событие ListBox.SelectedIndexChanged, чтобы обновлять данные поставщика.

0
ответ дан 24.11.2019, 13:33
  • 1
    Привет, спасибо за твой ответ, использовать Dataview вводит ту же проблему, внутри создана " instancia" dataset, поскольку структура этого теряется, теряя связи, окончательно оно не функционирует. Кроме того я не хочу использовать datagridviews. Я буду искать другое решение. – Fran Montserrat 28.08.2016, 14:05
  • 2
    Уже publiqu и # 233; другой пример, используя BindingSource вместо классов, которые ты не хочешь использовать, обрати внимание, если он подает тебя. – Aprendiendo.NET 29.08.2016, 08:23

Теги

Похожие вопросы