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