ORIENTACAO A OBJETOS - CONCEITO
Além do mais, eu, pessoalmente, acho melhor trabalhar com DataReader e criar métodos de extensão para overload nos métodos normais, por exemplo [Ô]GetString[Ô]. Ele aceita como parâmetro um inteiro que se refere ao número da coluna no DataReader. Eu uso métodos de extensão que recebem o nome do campo propriamente, assim, ao invés de fazer isso:
xxx.Nome = GetString(GetOrdinal([Ô]Nome[Ô]));
Eu faço isso:
xxx.Nome = GetString([Ô]Nome[Ô]);
O mesmo para todos os outros tipos de dados, todos é claro, já tratando DBNull.
Citação:Well, null is not an instance of any type. Rather, it is an invalid reference.
However, System.DbNull.Value, is a valid reference to an instance of System.DbNull (System.DbNull is a singleton and System.DbNull.Value gives you a reference to the single instance of that class) that represents nonexistent* values in the database.
*We would normally say null, but I don[ô]t want to confound the issue.
So, there[ô]s a big conceptual difference between the two. The keyword null represents an invalid reference. The class System.DbNull represents a nonexistent value in a database field. In general, we should try avoid using the same thing (in this case null) to represent two very different concepts (in this case an invalid reference versus a nonexistent value in a database field).
http://stackoverflow.com/questions/4958379/what-is-the-difference-between-null-and-system-dbnull-value
Será?
Não implementei a ideia de incluir uma List dentro de uma entidade (propriedade), achei mais fácil enviar o list separada ao método e trabalhar separadamente, pois não consegui ver como fazer isso no grid.
Numa tabela de colaboradores, povoo o grid com os dados do List<T> pai. Mas cada colaborador pode ter uma relação de e-mails de contato, de telefones, ou evidências de treinamentos, etc... o que seriam n List<T> de subitens. Sendo assim se a entidade colaborador tivesse um propriedades List para cada um desses grupos de dados, não saberia como fazer isso via DataGridView. Já que cada linha do grid é um registro do List Pai, os list filhos seriam só um campo, e como manipulá-los individualmente?
Além disso, como faço toda inclusão ou alteração diretamente no banco e não em lote (manipular o grid e só no final atualizar, isso porque posso ter n pessoas alterando a mesma tabela simultaneamente, e assim os dados de um usuário só estariam disponÃveis aos demais quando tudo fosse atualizado no final), achei mais pratico trabalhar os grupos de dados separadamente.
Outro assunto. Fiz o uso de interface para padronizar botões e seus métodos nos formulários. Assim a cada form tenho de implementar os métodos para não esquecer (ótimo). Com isso e o uso de delegates, consegui fazer uma barra de ferramentas no mdi ambiente que acessa todos os formulários para incluir, editar, consultar etc...tipo as IDEs do Word, Excel, etc... Deu um trabalhão, mas ficou ótimo.
Pelo que li aqui, tem muita coisa que poderia fazer meu programa ficar melhor, mas é tanta coisa ainda que desconheço, que estou fazendo o básico na [Ô]unha[Ô] mesmo, pois do contrário ainda nem teria começado o sistema.
Nota: Essa parte de manipular subgrupos de dados do List achei ótimo. e vai permitir criar recursos ótimos no programa sem ter de acessar o banco sempre. Muito legal, vou ver como implementar esses filtros.
Citação:Numa tabela de colaboradores, povoo o grid com os dados do List<T> pai. Mas cada colaborador pode ter uma relação de e-mails de contato, de telefones, ou evidências de treinamentos, etc... o que seriam n List<T> de subitens. Sendo assim se a entidade colaborador tivesse um propriedades List para cada um desses grupos de dados, não saberia como fazer isso via DataGridView. Já que cada linha do grid é um registro do List Pai, os list filhos seriam só um campo, e como manipulá-los individualmente?
Para cada click em uma linha do grid, você pode acessar a entidade correspondente na lista:
Private evento click
List<Cliente> clientes = (List<Cliente>)dgvMeuDataGrid.DataSource;
Cliente clienteSelecionado = clientes.ToArray()[e.RowIndex];
dgvGridContatos.DataSource = clienteSelecionado.Contatos; //onde contatos é a propriedade List<Contato>
Citação:Além disso, como faço toda inclusão ou alteração diretamente no banco e não em lote (manipular o grid e só no final atualizar, isso porque posso ter n pessoas alterando a mesma tabela simultaneamente, e assim os dados de um usuário só estariam disponÃveis aos demais quando tudo fosse atualizado no final), achei mais pratico trabalhar os grupos de dados separadamente.
Usando OOP, você pode manter um [Ô]pool de registros[Ô]. Quando um usuário instanciar um registro para alteração, você envia ao pool que usuário X está manipulando o registro. Ao mesmo tempo, quando um usuário disparar a ação de [Ô]Editar[Ô] um registro, você consulta o pool, para ver se o registro especificado está sendo usado. E quando o usuário terminar(gravar ou cancelar), você retira o registro do pool.
Citação:Outro assunto. Fiz o uso de interface para padronizar botões e seus métodos nos formulários. Assim a cada form tenho de implementar os métodos para não esquecer (ótimo). Com isso e o uso de delegates, consegui fazer uma barra de ferramentas no mdi ambiente que acessa todos os formulários para incluir, editar, consultar etc...tipo as IDEs do Word, Excel, etc... Deu um trabalhão, mas ficou ótimo.
Mais adiante, vou explicar sobre herança e você vai poder melhorar isso bastante...
Citação:Private evento click
List<Cliente> clientes = (List<Cliente>)dgvMeuDataGrid.DataSource;
Cliente clienteSelecionado = clientes.ToArray()[e.RowIndex];
dgvGridContatos.DataSource = clienteSelecionado.Contatos; //onde contatos é a propriedade List<Contato>
Achei isso muito bom, mas ficou uma dúvida: No caso desse Array que criou com o subgrupo (tabela relacionada), ele pode ter dois ou mais dados com tipos diferentes. (ID, Descrição, Inativo = boolean).
Nesse caso como ficaria o acesso a cada item dele, pois estes dados irão para outro grid do registro especÃfico selecionado do Pai para consulta e edição?
Citação:Usando OOP, você pode manter um [Ô]pool de registros[Ô].
Kerplunk não entendi isso. Como funciona essa tal pool de registros.
Citação:Achei isso muito bom, mas ficou uma dúvida: No caso desse Array que criou com o subgrupo (tabela relacionada), ele pode ter dois ou mais dados com tipos diferentes. (ID, Descrição, Inativo = boolean).
Nesse caso como ficaria o acesso a cada item dele, pois estes dados irão para outro grid do registro especÃfico selecionado do Pai para consulta e edição?
Não criei nenhum array. Veja bem o código:
- Na primeira linha, criei uma lista de clientes à partir do datasource do grid de clientes
- Na segunda criei uma instância de cliente, buscando em uma na lista pelo Ãtem especÃfico clicado. Explicando [Ô]ToArray()[Ô], é um método que transforma um List<T> em um array indexado, mas ele não vai modificar a lista original.
- Na terceira, em um outro grid, no caso [Ô]dgvGridContatos[Ô], estou passando como fonte de dados a propriedade [Ô]Contatos[Ô] da instância que de cliente que busquei na linha anterior. Não importam as propriedades que [Ô]Contatos[Ô] terão, elas serão colocadas no grid.
Citação:Kerplunk não entendi isso. Como funciona essa tal pool de registros.
Um pool de registros, é geralmente um webservice em que é mantido uma listagem de registros sendo editados. Quando o usuário abre para edição, por exemplo, um registro de cliente, eu envio para o pool de registros que usuário Zezinho está editando o objeto Cliente de Id XXXX. Ao mesmo tempo, na mesma inicialização do form de edição, eu consulto o pool de registros perguntando se tem algum usuário editando o objeto Cliente de id XXXX, como o Zezinho já abriu, quem quer que tenha aberto depois disso vai receber uma mensagem dizendo que o registro está sendo editado. Com isso, entra uma das coisas que uso direto, o UID de registro. Todas as minhas tabelas, o primeiro campo(e geralmente chave primária), é um GUID. GUID, é um tipo de dados muito útil. Com ele, cada REGISTRO vai ser único, de verdade. Imagine a situação:
Você tem tabela de clientes, produtos e fornecedores. Em cada uma delas, o campo chave primária é um inteiro. Portanto, é muito possÃvel ter um cliente com ID=1, também um fornecedor e também um produto. Portanto, cada registro vai ser único em sua respectiva tabela, mas nunca vai ser único no banco de dados. Isso é praticamente impossÃvel de ocorrer usando GUID. As vantagens do uso do GUID:
- Registros são únicos tanto no seu quanto em qualquer banco de dados no mundo. Ou seja, se você tem um registro de um determinado GUID, aquele mesmo GUID não vai existir em nenhum outro banco de dados no mundo todo, visto que o GUID é formado levando em conta vários fatores, incluindo alguns próprios de cada máquina, isso os torna únicos no mundo.
- Por ter registros únicos, é muito mais simples saber [Ô]o que é o que[Ô], você pode ter simplesmente um guid qualquer e procurar em todas as tabelas do sistema, se ele for do seu banco de dados, você vai ter um registro, o que não acontece usando inteiros, visto que os registros são únicos apenas a nÃvel de tabela.
Desvantagens do GUID:
- é um tipo de dados bem complexo e case-sensitive. Por isso, o valor dele é muito difÃcil de ser lido por um humano e não serve para isso. Mas aÃ, entra uma outra [Ô]manha do malandro[Ô], se você precisar passar um GUID para um cliente por alguma razão qualquer(um boleto, por exemplo), você pode manter uma tabela de [Ô]atalhos de GUID[Ô], que nada mais é que uma tabela contendo uma chave primária GUID, um segundo campo também GUID(que é o GUID que você vai passar para o cliente) e um terceiro campo inteiro auto-incrementado. Então, precisando passar um GUID para o cliente, adicione na tabela de atalhos, que vai devolver um inteiro que é o que você vai passar para o cliente. Quando e se o cliente precisar dar algum retorno sobre o que você passou, ele vai passar esse número inteiro e você procura na tabela de atalhos o GUID correspondente para buscar o registro na sua tabela. Mas tudo isso, somente caso precise passar esse registro para outra pessoa e mesmo assim, nada impede de se passar o guid diretamente, essa tabela de [Ô]atalhos[Ô] é opcional.
Toda essa explicação, não tem muito a haver com um pool de regitros, mas usando identificadores GUID, você pode manter o pool com mais facilidade, sem precisar especificar objeto.
O pool de registros, também é útil para manter múltiplos estados de edição e operações de múltiplos estágios. Por exemplo, uma operação de transporte de carga. Tem o estágio de [Ô]separando mercadorias[Ô], [Ô]trâmites aduaneiros[Ô], [Ô]carregamento[Ô], [Ô]transporte[Ô], [Ô]descarga[Ô] e [Ô]finalização[Ô] (tudo isso, por exemplo). Então, você faz um conhecimento de frete que vai conter as mercadorias que vão ser transportadas. e inicia a [Ô]separação de mercadorias[Ô], então manda para o pool de registros que o conhecimento de guid XXXXX está em estágio de [Ô]separação de mercadorias[Ô]. Qualquer um que tentar editar o conhecimento ou fazer uma operação que não é a da ordem cronológica da sequência, vai receber um [Ô]não pode fazer isso[Ô] do pool de registros. Esse pool de registros, pode ter um leitor online, uma página, onde o que se passa em um determinado registro no pool é mostrado. Usando o mesmo exemplo acima(do transporte), um cliente que vai receber a mercadoria, sabe em que estágio está o pedido dele. Note que isso é apenas um exemplo, existem muitas situações em que isso pode ser aplicado. Já implementei um pool de registros para a Massey Ferguson, que tinha muitos estágios. O cliente comprava uma colheitadeira por exemplo, e esse cliente podia acompanhar no site em que estágio estava o pedido dele, desde a montagem de cada parte da máquina(bloco, motor...), até o transporte e até mesmo em alguns casos, onde estava o caminhão transportando sua máquina.