LINQ - Usando ComboBox com dados relacionados
Você já notou que eu não paro de escrever sobre o LINQ , realmente eu gostei muito dos recursos que ele oferece e acho que se usado com bom senso trás grandes facilidades aos que gostam de desenvolver usando banco de dados.
Então vamos a mais um artigo sobre o LINQ, desta vez eu vou mostrar como podemos usar dados de tabelas relacionadas com ComboBox em aplicações Windows Forms.
Eu vou usar o LINQ To SQL , e apenas para lembrar , ele só funciona com o SQL Server.
No exemplo deste artigo vou configurar uma combobox para filtrar registros que serão exibidos em um datagridview. É um conceito básico e clássico muitas vezes abordado em muitos artigos. O cenário é o seguinte:
- Temos um banco de dados SQL Server, no exemplo eu vou usar o nosso saco de pancadas: Northwind.mdf;
- Temos duas tabelas relacionadas; vamos usar as tabelas Products e Categories;
O relacionamento entre essas tabelas é mostrado na figura abaixo:
- Temos uma combobox que irá exibir todas as categorias da tabela Categories (registros da tabela Pai);
- Temos um datagridview que irá exibir os produtos da tabela Products relacionados a categoria selecionada no combobox (registros da tabela filha);
Vamos fazer isso usando LINQ To SQL e portanto vou usar o Visual Basic 2008 Express Edition.
Crie uma nova aplicação do tipo Windows Forms Application com o nome de LINQ_ComboBox;
Defina uma conexão com o banco de dados Northwind.mdf.
A seguir vamos incluir uma referência ao LINQ To SQL, selecione no menu a opção Project -> Add New Item;
Na janela Add New Item , selecione o template LINQ to SQL Classes e informe o nome Northwind.dbml (o nome pode ser qualquer um ao seu critério)
Com isso poderemos gerar o mapeamento entre as tabelas do banco de dados e os objetos relacionados pois o LINQ irá gerar automaticamente classes para as tabelas mapeadas permitindo que sejam executadas operações como consulta e atualização usando a sintaxe LINQ. Uma das vantagem disso é que passamos a ter uma verificação em tempo de compilação e uma sintaxe única baseada no código Visual Basic sem ter comandos SQL embutidos no código.
Será aberta o descritor Objeto-Relacional , vamos então arrastar as tabelas Products e Categories a partir da janela DataBase Explorer para o descritor Objeto Relacional:
O descrito O/R gerou as classes Category e Product e atribui uma associação entre elas inferindo assim o relacionamento entre as tabelas. A classe Category contém uma coleção de classes Product chamada Products.
Você pode espiar o código gerado no arquivo Northwind.designer.vb (expanda os objetos na janela Solution Explorer)
Estamos pronto para trabalhar com a interface do cliente usando o formulário Windows. Quando trabalhamos com dados vinculados em formulários Windows usamos a janela Data Sources onde arrastamos as tabelas do banco de dados para criar e vincular os controles para exibição dos dados.
O gerenciamento dos dados com os controles e a fonte de dados é feita pelo BindingSource de forma transparente, e, ele pode gerenciar dados vinculados entre os controles e qualquer tipo de fonte de dados, incluindo coleções de objetos e não apenas DataSets, desta forma podemos usar os mesmos recursos com as classes do LINQ To SQL.
Vamos então abrir a janela Data Sources a partir do menu Data -> Show Data Sources, e , a seguir clique no link: Add New Data Source;
A seguir na janela Choose Data Source type selecione o tipo Object;
A seguir clique no botão Next> e vamos selecionar o objeto com o qual desejamos efetuar a vinculação. Vamos selecionar a classe Category pois esta classe ja contém uma coleção de produtos que iremos usar no nosos formulário.
Clique em Next> e a seguir em Finish e você verá na janela Data Sources a classe Category e a coleção de produtos;
Selecione o formulário form1.vb e na janela Data Source selecione Category alterando o seu modo de exibição para ComboBox;
Altera também o modo de exibição de Products para DataGridView.
Feito estes ajustes arraste a classe Category e a classe Products para formulário form1.vb conforme o leiaute abaixo:
Ao arrastar o objeto Category serão criados os objetos CategoryBindingSource e CategoryBindingNavigator no formulário. Podemos deletar o objeto CategoryBindingNavigator pois usaremos a combobox para selecionar os registros.Ao arrastar o objeto Products será criado o objeto ProductsBindingSource.
A chave para que a vinculação de dados entre os controles seja feita de forma sincronizada é que a propriedade DataSource do BindingSource filho deve estar definida para o BindingSource pai e a propriedade DataMember do BindingSource filho deve estar definida para o nome do relacionamento que neste caso é o nome da coleção filho : Products. Abaixo temos uma visão destas configurações que foram definidas automaticamente:
Se fosse feito via código teriamos o seguinte:
Me.CategoryComboBox.DataSource = Me.CategoryBindingSource Me.CategoryComboBox.DisplayMember = "CategoryName" Me.ProductsBindingSource.DataMember = "Products" Me.ProductsBindingSource.DataSource = Me.CategoryBindingSource
Se você espiar o código gerado não vai encontrar pois o descritor não preenche os controles com os dados. Temos que fazer isso via código. Abaixo temos o código que é preciso para preencher os controles com dados vinculados:
A classe NorthwindDataContext é a classe que foi gerada quando nós criamos o nosso modelo objeto relacional northwind.dbml. Ela gerencia a conexão entre as classes LINQ To SQL e o banco de dados cuidando também das alterações feitas nos objetos Category e Product.
Tudo que precisamos fazer é definir a propriedade DataSource do CategoryBindingSource igual a propriedade Categories do DataContext (db). Fazendo assim iremos iniciar a carga de todas as categorias a partir do banco de dados e iremos criar uma coleção de objetos Category.
Note que não estamos carregando especificamente nenhum produto pois por padrão o LINQ To SQL usa o lazy loading , ou carregamento tardio, para as coleções relacionadas de forma os produtos serão carregados somente quando uma categoria for selecionada.
Executando o projeto teremos:
Aguarde mais artigos sobre LINQ.
Pegue o projeto completo aqui: LINQ_ComboBox.zip
Eu sei é apenas LINQ mas eu gosto...
Rom 3:23 Porque todos pecaram e destituídos estão da glória de Deus;
Rom 3:24 sendo justificados gratuitamente pela sua graça, mediante a redenção que há em Cristo Jesus,
Rom 3:25 ao qual Deus propôs como propiciação, pela fé, no seu sangue, para demonstração da sua justiça por ter ele na sua paciência, deixado de lado os delitos outrora cometidos;
Rom 3:26 para demonstração da sua justiça neste tempo presente, para que ele seja justo e também justificador daquele que tem fé em Jesus.
Referências:
José Carlos Macoratti