none
Datatables em memória RRS feed

  • Pergunta

  • Olá amigos!

    Eu consigo trabalhar com dois datatables como mestre-detalhes em memória? Por exemplo, no dtpai eu crio um novo registro e no dtFilho 05 registros deste pai, porém como eu vinculo os filhos se o pai ainda não existe? Como persistir isso no banco no final? Isso tudo é possível, mesmo utilizando outros recursos como linq? Obrigado.

     

    quarta-feira, 1 de outubro de 2014 15:43

Respostas

  • Da pra fazer sim, vc trabalha normal, como se fosse no banco, pra vc vinculá-los, vc cria uma coluna de id no pai e uma idPai no filho, então gera um ID novo a cada inserção no pai e replica ele no filho, depois pra passar pro banco, se seu campo de id for identity o banco se vira, só vc ir passando o pai e os filhos.

    Da um pouco de trampo, mas é tranquilo.

    dim dtPai as new datatable
    dtPai.Columns.Add("ID", gettype(integer))
    dtPai.Columns.Add("Outros", gettype(string))
    ....
    
    dim dtFilho as new datatable
    dtFilho.Columns.Add("ID", gettype(integer))
    dtFilho.Columns.Add("IDPai", gettype(integer))
    dtFilho.Columns.Add("Outros", gettype(string))
    ...
    
    Dim drPai as DataRow = dtPai.newRow
    dim idPai = 1 'Aqui vc gera seu id
    drPai("ID") = idPai 
    drPai("Outros") = "Dados"
    dtPai.rows.add(drPai)
    
    dim drFilho as DataRow = dtFilho.newRow
    drFilho("ID") = 1 'Aqui gera o id do filho
    drFilho("IDPai") = idPai
    drFilho("Outros") = "Dados"
    dtFilho.rows.add(drFilho)
    

    Depois pra gravar no banco vc vai fazendo os inserts dentro de um for.

    Espero ter ajudado.

    Flw

    quinta-feira, 2 de outubro de 2014 13:07
  • Nao seria mais facil criar uma classe Pai e Filho,uma collection de cada um e depois inserir no banco?

    Pelo menos voce nao instancia a classe DataTable e consome apenas alguns itens desse objeto
    siga meu exemplo (usando LinqToSQL) é mais extenso porem garanto melhor performance

    Classe PAI:

    Public Class cPai
        Dim xCodigo As Integer
    
        Public Property CodigoPai As Integer
            Get
                Return xCodigo
            End Get
            Set(value As Integer)
                xCodigo = value
            End Set
        End Property
    
        Dim xNome As String
    
        Public Property NomePai As String
            Get
                Return xNome
            End Get
            Set(value As String)
                xNome = value
            End Set
        End Property
    End Class

    Classe Filho:

    Public Class cFilho
        Dim xCodFilho As Integer
    
        Public Property CodigoFilho As Integer
            Get
                Return xCodFilho
            End Get
            Set(value As Integer)
                xCodFilho = value
            End Set
        End Property
    
        Dim xNomeFilho As String
    
        Public Property NomeFilho As String
            Get
                Return xNomeFilho
            End Get
            Set(value As String)
                xNomeFilho = value
            End Set
        End Property
    
        Dim xCodigoPai As Integer
    
        Public Property CodigoFilhoPai As Integer
            Get
                Return xCodigoPai
            End Get
            Set(value As Integer)
                xCodigoPai = value
            End Set
        End Property
    End Class

    Agora o codigo que irá trabalhar com essas instancias:

        Dim lPai As New List(Of cPai)
        Dim lFilho As New List(Of cFilho)
    
        Private Sub AddPai(strNome As String, intCodigo As Integer)
            'salva a instancia filho na list
            Dim clsPai As New cPai
            Dim existe = lPai.Any(Function(f) f.CodigoPai.Equals(intCodigo) Or f.NomePai.Equals(strNome))
            If (Not existe) Then
                clsPai.CodigoPai = intCodigo
                clsPai.NomePai = strNome
                Me.lPai.Add(clsPai)
            Else
                MsgBox("Ja existe um PAI com este nome ou codigo")
            End If
        End Sub
    
        Private Sub AddFilho(strNome As String, intCodigo As Integer, intCodigoPai As Integer)
            'adiciona a instancia filho numa list criada para essa classe
            Dim clsFilho As New cFilho
            'linq to sql verificando se o pai realmente citado existe
            'e se o codigo do filho ja existe na list
            Dim existePai = lPai.Any(Function(f) f.CodigoPai.Equals(intCodigoPai))
            Dim existeFilho = lFilho.Any(Function(f) f.CodigoFilho.Equals(intCodigo) Or f.NomeFilho.Equals(strNome))
            If (Not existeFilho) Then
                If (existePai) Then
                    clsFilho.CodigoFilho = intCodigo
                    clsFilho.CodigoFilhoPai = intCodigoPai
                    clsFilho.NomeFilho = strNome
                    lFilho.Add(clsFilho)
                Else
                    MsgBox("O codigo do pai e invalido!!!")
                End If
            Else
                MsgBox("Filho ja cadastrado com esse nome ou codigo")
            End If
    
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Call AddFilho(Me.TextBox5.Text, TextBox3.Text, TextBox4.Text)
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Call AddPai(Me.TextBox2.Text, CInt(TextBox1.Text))
        End Sub
    
        Private Sub Banco()
            'seleciona o pai e o filho e exibe num listbox,pode ser implementada uma rotina de banco de dados
            Dim insere = From _pai In lPai.Cast(Of cPai)(), _filho In lFilho.Cast(Of cFilho)() Where _pai.CodigoPai = _filho.CodigoFilhoPai
                      Select New With {_filho.NomeFilho, _pai.NomePai}
    
            'exibe o resultado na list
            For Each valor In insere
                Me.ListBox1.Items.Add(String.Concat("PAI:", valor.NomePai, " - ", "FILHO:", valor.NomeFilho))
            Next
        End Sub
    
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            Me.ListBox1.Items.Clear()
            Call Banco()
        End Sub

    Só mude o for each nao para exibir numa list e sim para inserir no banco...

    dessa forma voe cria os objetos da forma que voce quer,sem precisar usar recursos da classe System.Data sem

    necessidade


    Microsoft Technology Associate (MTA)


    sexta-feira, 3 de outubro de 2014 17:13

Todas as Respostas

  • Leandro como assim vincular os filhos se o pai ainda não exite? Posta algum exemplo.
    quarta-feira, 1 de outubro de 2014 21:36
  • Da pra fazer sim, vc trabalha normal, como se fosse no banco, pra vc vinculá-los, vc cria uma coluna de id no pai e uma idPai no filho, então gera um ID novo a cada inserção no pai e replica ele no filho, depois pra passar pro banco, se seu campo de id for identity o banco se vira, só vc ir passando o pai e os filhos.

    Da um pouco de trampo, mas é tranquilo.

    dim dtPai as new datatable
    dtPai.Columns.Add("ID", gettype(integer))
    dtPai.Columns.Add("Outros", gettype(string))
    ....
    
    dim dtFilho as new datatable
    dtFilho.Columns.Add("ID", gettype(integer))
    dtFilho.Columns.Add("IDPai", gettype(integer))
    dtFilho.Columns.Add("Outros", gettype(string))
    ...
    
    Dim drPai as DataRow = dtPai.newRow
    dim idPai = 1 'Aqui vc gera seu id
    drPai("ID") = idPai 
    drPai("Outros") = "Dados"
    dtPai.rows.add(drPai)
    
    dim drFilho as DataRow = dtFilho.newRow
    drFilho("ID") = 1 'Aqui gera o id do filho
    drFilho("IDPai") = idPai
    drFilho("Outros") = "Dados"
    dtFilho.rows.add(drFilho)
    

    Depois pra gravar no banco vc vai fazendo os inserts dentro de um for.

    Espero ter ajudado.

    Flw

    quinta-feira, 2 de outubro de 2014 13:07
  • Nao seria mais facil criar uma classe Pai e Filho,uma collection de cada um e depois inserir no banco?

    Pelo menos voce nao instancia a classe DataTable e consome apenas alguns itens desse objeto
    siga meu exemplo (usando LinqToSQL) é mais extenso porem garanto melhor performance

    Classe PAI:

    Public Class cPai
        Dim xCodigo As Integer
    
        Public Property CodigoPai As Integer
            Get
                Return xCodigo
            End Get
            Set(value As Integer)
                xCodigo = value
            End Set
        End Property
    
        Dim xNome As String
    
        Public Property NomePai As String
            Get
                Return xNome
            End Get
            Set(value As String)
                xNome = value
            End Set
        End Property
    End Class

    Classe Filho:

    Public Class cFilho
        Dim xCodFilho As Integer
    
        Public Property CodigoFilho As Integer
            Get
                Return xCodFilho
            End Get
            Set(value As Integer)
                xCodFilho = value
            End Set
        End Property
    
        Dim xNomeFilho As String
    
        Public Property NomeFilho As String
            Get
                Return xNomeFilho
            End Get
            Set(value As String)
                xNomeFilho = value
            End Set
        End Property
    
        Dim xCodigoPai As Integer
    
        Public Property CodigoFilhoPai As Integer
            Get
                Return xCodigoPai
            End Get
            Set(value As Integer)
                xCodigoPai = value
            End Set
        End Property
    End Class

    Agora o codigo que irá trabalhar com essas instancias:

        Dim lPai As New List(Of cPai)
        Dim lFilho As New List(Of cFilho)
    
        Private Sub AddPai(strNome As String, intCodigo As Integer)
            'salva a instancia filho na list
            Dim clsPai As New cPai
            Dim existe = lPai.Any(Function(f) f.CodigoPai.Equals(intCodigo) Or f.NomePai.Equals(strNome))
            If (Not existe) Then
                clsPai.CodigoPai = intCodigo
                clsPai.NomePai = strNome
                Me.lPai.Add(clsPai)
            Else
                MsgBox("Ja existe um PAI com este nome ou codigo")
            End If
        End Sub
    
        Private Sub AddFilho(strNome As String, intCodigo As Integer, intCodigoPai As Integer)
            'adiciona a instancia filho numa list criada para essa classe
            Dim clsFilho As New cFilho
            'linq to sql verificando se o pai realmente citado existe
            'e se o codigo do filho ja existe na list
            Dim existePai = lPai.Any(Function(f) f.CodigoPai.Equals(intCodigoPai))
            Dim existeFilho = lFilho.Any(Function(f) f.CodigoFilho.Equals(intCodigo) Or f.NomeFilho.Equals(strNome))
            If (Not existeFilho) Then
                If (existePai) Then
                    clsFilho.CodigoFilho = intCodigo
                    clsFilho.CodigoFilhoPai = intCodigoPai
                    clsFilho.NomeFilho = strNome
                    lFilho.Add(clsFilho)
                Else
                    MsgBox("O codigo do pai e invalido!!!")
                End If
            Else
                MsgBox("Filho ja cadastrado com esse nome ou codigo")
            End If
    
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Call AddFilho(Me.TextBox5.Text, TextBox3.Text, TextBox4.Text)
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Call AddPai(Me.TextBox2.Text, CInt(TextBox1.Text))
        End Sub
    
        Private Sub Banco()
            'seleciona o pai e o filho e exibe num listbox,pode ser implementada uma rotina de banco de dados
            Dim insere = From _pai In lPai.Cast(Of cPai)(), _filho In lFilho.Cast(Of cFilho)() Where _pai.CodigoPai = _filho.CodigoFilhoPai
                      Select New With {_filho.NomeFilho, _pai.NomePai}
    
            'exibe o resultado na list
            For Each valor In insere
                Me.ListBox1.Items.Add(String.Concat("PAI:", valor.NomePai, " - ", "FILHO:", valor.NomeFilho))
            Next
        End Sub
    
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            Me.ListBox1.Items.Clear()
            Call Banco()
        End Sub

    Só mude o for each nao para exibir numa list e sim para inserir no banco...

    dessa forma voe cria os objetos da forma que voce quer,sem precisar usar recursos da classe System.Data sem

    necessidade


    Microsoft Technology Associate (MTA)


    sexta-feira, 3 de outubro de 2014 17:13
  • Ajudou sim. Perdão por não responder e marcar antes mas estava empenhado no projeto e não pude entrar para ver os resultados do Fórum. Aliás obrigado a todos pela ajuda.
    domingo, 5 de outubro de 2014 00:11