VB .NET 2008 - Apresentando o LINQ To DataSet


O DataSet é uma representação de dados em memória muito útil e atua como o centro de uma vasta variedade de de aplicações baseados em dados. Quando um DataSet é preenchido com dados , isto é feito geralmente usando um DataAdapter. O DataAdapter geralmente restringe os dados que serão carregados no DataSet.

Uma vez que os dados estejam carregados existe uma necessidade de construir consultas adicionais aos dados. É aqui que LINQ to DataSet entra em cena pois LINQ to DataSet permite que os desenvolvedores escrevam consultas sobre um DataSet existente. (LINQ to DataSet suporat datasets tipados e não tipados).

Os métodos existentes que podem ser usados para escrever consultas contra um DataSet utilizam expressões strings que possuem uma sintaxe semelhante a SQL. Embora estas expressões funcionem bem elas estão restritas a um conjunto limitado de operadores que existem em um DataSet e devido ao fato de que elas são baseadas em strings não possuem qualquer verificação em tempo de compilação para validação; além disso elas são outra linguagem que o desenvolvedor precisa aprender.

O LINQ permite que as consultas sejam escritas na própria linguagem de desenvolvimento e fornece a verificação em tempo de compilação. Além disso LINQ permite que todo o recurso do framework seja usado durante a criação das consultas.

Existem duas formas básicas de usar LINQ em sua aplicação: Usar Query Expressions e Method Queries.

As Query Expressions têm a vantagem de ser muito parecida com as instruções SQL de forma que a curva de aprendizado é mais suave. Por exemplo, se você deseja encontrar todos os clientes cujo último nome for igual a Smith selecionando o primeiro nome você pode escrever a seguinte Query Expression:

 

var query = From r in customerDataTable.AsEnumerable()
                   Where r.Field<string>("LastName") == "Smith"
                   Select r.Field<string>(“FirstName”);

a mesma consulta usando Method Queries ficaria assim:

var query = customerDataTable.AsEnumerable()
                 .Where(dr => dr.Field<string>("LastName") == "Smith")
                 .Select(dr => dr.Field<string>("FirstName"));

Da para notar que usar Query Expression é muito mais amigável.

Vejamos um exemplo de como usar LINQ To DataSet usando o Visual Basic 2008 Express Edition.

Abra o Visual Basic 2008 Express Edition e crie um novo projeto do tipo Windows Forms ;

Na partir do menu Data selecione Add New Data Source e na janela do assistente selecione DataBase e clique em Next>

A seguir defina uma nova conexão com o banco de dados Northwind.mdf (se ela não existir) e clique no botão Next>

A seguir confirme que você deseja salvar a string de conexão no arquivo de configuração e clique em Next>

Na janela a seguir expanda os objetos tables e selecione agora as tabelas Categories e Products , aceite o nome padrão sugerido para o Data Source e clique a seguir em Finish;

Na janela Solution Explorer selecione o DataSet criado - NORTHWINDDataSet e você verá as tabelas Categories e Products e os respectivos TableAdapters criados;

Selecione o formulário form1.vb e abra a janela Data Sources. Arraste o objeto Categories para o formulário e, em seguida arraste o objeto Products para o mesmo formulário conforme figura abaixo:

Você deverá ver os objetos BindingSource , BindingNavigator e TableAdapter serem criados na base do formulário.

Até o momento não usamos LINQ no projeto e se o mesmo for executado irá exibir , em uma estrutura mestre-detalhes , as categorias no primeiro Grid e os produtos relacionados no segundo Grid; de forma que a seleção de uma categoria no primeiro grid mostra os produtos relacionados no segundo.

Vamos então usar o LINQ To DataSet para criar uma consulta que calcule o valor total dos produtos que não estejam descontinuados por categoria.

No evento CurrentChanged do componente CategoriesBindingSource inclua o seguinte código:

Private Sub CategoriesBindingSource_CurrentChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CategoriesBindingSource.CurrentChanged
Dim row As NORTHWNDDataSet.CategoriesRow
row = CType(CType(Me.CategoriesBindingSource.Current, DataRowView).Row, NORTHWNDDataSet.CategoriesRow)

Dim total =  Aggregate Produtos In Me.NORTHWNDDataSet.Products _
                  Where Produtos.CategoryID = row.CategoryID AndAlso _
                  Produtos.Discontinued = False _
                  Into Sum(Produtos.UnitPrice * Produtos.UnitsInStock)

End Sub

Para exibir o valor calculado vamos incluir um controle TextBox a partir da ToolBox no formulário, aproveite e remova algumas colunas do Grid que exibe os produtos de forma que leiaute fique conforme abaixo;

Agora completo o código de forma a exibir o valor formato para moeda no TextBox:

Private Sub CategoriesBindingSource_CurrentChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CategoriesBindingSource.CurrentChanged
Dim row As NORTHWNDDataSet.CategoriesRow
row = CType(CType(Me.CategoriesBindingSource.Current, DataRowView).Row, NORTHWNDDataSet.CategoriesRow)

Dim total = Aggregate Produtos In Me.NORTHWNDDataSet.Products _
                  Where Produtos.CategoryID = row.CategoryID AndAlso _
                  Produtos.Discontinued = False _
                  Into Sum(Produtos.UnitPrice * Produtos.UnitsInStock)

                 Me.TextBox1.Text = Format(total, "c")
End Sub

Executando o projeto iremos ter o resultado exibido na figura abaixo, onde os valores totais dos produtos não descontinuados por categoria, são exibidos no DataGridView vinculados a tabela de Categorias de forma que selecionando uma categoria vemos os produtos e os totais da categoria.

Eu sei é apenas VB .NET mas eu gosto...

Referências:

http://blogs.msdn.com/adonet/archive/2007/01/26/querying-datasets-introduction-to-linq-to-dataset.aspx
http://blogs.msdn.com/erickt/archive/2007/08/24/linq-to-dataset-data-binding.aspx
http://blogs.msdn.com/erickt/archive/2007/10/05/linq-to-dataset-data-binding-introducing-linqdataview.aspx

101 LINQ Samples


José Carlos Macoratti