Exemplo de Aplicação Introdução ao ASP.NET – Módulo 07 – ADO.NET

Bom dia a todos.

Segue o exemplo implementado da aula de número 07 – Acesso a Dados utilizando SqlClient. Logo estarei disponibilizando o mesmo exemplo utilizando Entity Framework 6.0.

Segue descrição:

Projeto Veiculos DB

Está solução está dividida em 6 projetos, sendo eles:

1- FFB.Modulo7.Projeto: Projeto do tipo Web Application responsável por exibir ao usuário a interface Web com os formulários de consulta, adição, edição e remoção de dados (CRUD)

2- FFB.Modulo7.Entidades: Projeto do tipo Class Library que contém as Entidades (classes de domínio) da nossa solução. As entidades seguem a metodologia POCO (Plain Old CLR Objects) permitindo assim o uso das entidades através de uma framework de ORM (Object Relation-Mapping ou Mapeamento de Objeto Relacional, por exemplo Entity Framework ou NHibernate).

3- FFB.Modulo7.DAO: Projeto do tipo Class Library que contém apenas a interface IDAO (Interface com os métodos básicos a serem implementados por todas as classes DAO). Este projeto está a parte para permitir a implementação de outra camada DAO utilizando outras tecnologias, mantendo o baixo acoplamento entre a camada Controle e a de acesso a dados e com isto permitir a troca rápida e até em tempo de execução da camada de persistência.

4- FFB.Modulo7.ADONET.DAO: Projeto do tipo Class Library que contém a implementação de persistência utilizando as classes de acesso a dados do ADO.NET (SqlClient).

5- FFB.Modulo7.ADONET.DAO.Teste: Projeto do tipo Unit Test que realiza os testes unitários para a camada de acesso a dados.

6- FFB.Modulo7.Controle: Projeto do tipo Class Library que contém as classes de controle que realizam a chamada as camadas DAO.

Segue o diagrama da estrutura básica de dependências do Projeto

Imagem

 

Configuração:

1- Baixar e instalar o SQL Server 2008 Management Studio (http://www.microsoft.com/en-us/download/details.aspx?id=7593)

2- Após a instalação do Management Studio, deve-se verificar se a máquina contém alguma instância do SQL Server, para isto, na tela inicial da aplicação, aonde se pede o nome do Servidor, clique em BROWSE FOR MORE, expanda DATABASE ENGINE para ver o nome da instância instalada. Se nenhum aparecer, proceder com a instalação abaixo:

3- Baixar e instalar o SQL Server 2008, 2012 ou 2014 Express, Developer ou Professional. Por padrão o Express é instalado junto ao Visual Studio. Segue o link ensinando como verificar qual versão você já tem instalado do SQL na sua máquina: http://support.microsoft.com/kb/321185/pt-br

4- Executar o script abaixo para criar a base de dados

USE [master]
GO
/****** Object:  Database [VeiculosDB]    Script Date: 06/22/2014 11:07:44 ******/
CREATE DATABASE [VeiculosDB]
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [VeiculosDB].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [VeiculosDB] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [VeiculosDB] SET ANSI_NULLS OFF
GO
ALTER DATABASE [VeiculosDB] SET ANSI_PADDING OFF
GO
ALTER DATABASE [VeiculosDB] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [VeiculosDB] SET ARITHABORT OFF
GO
ALTER DATABASE [VeiculosDB] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [VeiculosDB] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [VeiculosDB] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [VeiculosDB] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [VeiculosDB] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [VeiculosDB] SET CURSOR_DEFAULT  GLOBAL
GO
ALTER DATABASE [VeiculosDB] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [VeiculosDB] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [VeiculosDB] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [VeiculosDB] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [VeiculosDB] SET  ENABLE_BROKER
GO
ALTER DATABASE [VeiculosDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [VeiculosDB] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [VeiculosDB] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [VeiculosDB] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [VeiculosDB] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [VeiculosDB] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [VeiculosDB] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [VeiculosDB] SET  READ_WRITE
GO
ALTER DATABASE [VeiculosDB] SET RECOVERY FULL
GO
ALTER DATABASE [VeiculosDB] SET  MULTI_USER
GO
ALTER DATABASE [VeiculosDB] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [VeiculosDB] SET DB_CHAINING OFF
GO
EXEC sys.sp_db_vardecimal_storage_format N'VeiculosDB', N'ON'
GO
USE [VeiculosDB]
GO
/****** Object:  Table [dbo].[Marca]    Script Date: 06/22/2014 11:07:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Marca](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Nome] [nvarchar](max) NOT NULL,
PRIMARY KEY CLUSTERED
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Modelo]    Script Date: 06/22/2014 11:07:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Modelo](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Nome] [nvarchar](max) NOT NULL,
	[Marca_Id] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Moto]    Script Date: 06/22/2014 11:07:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Moto](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[AnoFabricacao] [int] NOT NULL,
	[AnoModelo] [int] NOT NULL,
	[Chassi] [nvarchar](20) NOT NULL,
	[Cor] [nvarchar](max) NOT NULL,
	[Modelo_Id] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Carro]    Script Date: 06/22/2014 11:07:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Carro](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[AnoFabricacao] [int] NOT NULL,
	[AnoModelo] [int] NOT NULL,
	[Chassi] [nvarchar](20) NOT NULL,
	[Cor] [nvarchar](max) NOT NULL,
	[QtdPortas] [int] NOT NULL,
	[Modelo_Id] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  ForeignKey [FK__Modelo__Marca_Id__0519C6AF]    Script Date: 06/22/2014 11:07:46 ******/
ALTER TABLE [dbo].[Modelo]  WITH CHECK ADD FOREIGN KEY([Marca_Id])
REFERENCES [dbo].[Marca] ([Id])
GO
/****** Object:  ForeignKey [FK__Moto__Modelo_Id__0EA330E9]    Script Date: 06/22/2014 11:07:46 ******/
ALTER TABLE [dbo].[Moto]  WITH CHECK ADD FOREIGN KEY([Modelo_Id])
REFERENCES [dbo].[Modelo] ([Id])
GO
/****** Object:  ForeignKey [FK__Carro__Modelo_Id__09DE7BCC]    Script Date: 06/22/2014 11:07:46 ******/
ALTER TABLE [dbo].[Carro]  WITH CHECK ADD FOREIGN KEY([Modelo_Id])
REFERENCES [dbo].[Modelo] ([Id])
GO

5- Alterar a String de Conexão no Arquivo Web.Config e também no App.Config no projeto do Teste unitário, alterando a tag Data Source = para o nome doServidor\Instância caso tenha. Por exemplo connectionString=“Data Source=NOMEMAQUINA\SqlExpress;Initial Catalog=VeiculosDB;Integrated Security=True”

O projeto foi compilado no Visual Studio 2010 utilizando a .Net Framework 4.0

Segue link para download
-Slides: Modulo7
Exemplo: https://www.dropbox.com/s/dr2yrok7kynfn3d/FFB.Modulo7.Projeto.rar 

 

Publicado em ASP.NET, C#, LINQ, MasterPage, Orientação a Objeto, Sem categoria, System.Data.SqlClient, VS2010 | Marcado com , , , , , , | Deixe um comentário

PhotoOrganizer – Brincando com Diretórios e Arquivos através do System.IO

Pessoal, bom dia

Uma coisa boa de quem sabe programar, ou quer aprender, é sempre poder criar ferramentas para resolver os seus problemas sem ter de recorrer a programas da internet que por vezes não funcionam, carregam vírus e trojans ou não servem totalmente a nossa necessidade.

Pensando nisto surgiu a minha problemática:
Eu e minha esposa mantemos um Ateliê de Artes e Artigos de festa infantis (https://www.facebook.com/AtelieFlordePapel) eu sou o responsável por realizar todas as artes e para isto preciso salvar muitas imagens da internet. Um belo dia meu HD do notebook já estava quase cheio e verifiquei que eu tinha muitos arquivos repetidos, surgiu a ideia, vou criar uma aplicação para MOVER meus arquivos repetidos para um diretório a parte e de lá eu analiso e excluo eles.

A ideia é interessante, criei o Projeto PhotoOrganizer no #VS2013, porém, por que criar uma código que só funciona com foto, vamos fazer de forma que aceite qualquer tipo de arquivo.

Agora, vamos estudar a forma de comparação:

  1. Realizar a comparação através de nome dos arquivos: Não dá certo, A comparação que quero fazer é de conteúdo, nome não me diz nada.
  2. Comparar o Conteúdo do arquivo: Através da analise dos binários do arquivo eu consigo saber se eles são iguais, porém, é uma varredura um pouco mais lenta dependendo do tamanho do arquivo, precisamos criar uma verificação preliminar
  3. Comparar o Tamanho dos arquivos: Opa, agora sim…verifico se os arquivos tem o mesmo tamanho, se tiverem já é um possível sinal que são iguais, e trata-se de uma comparação bem mais rápida de ser feita. Caso eles tenham o mesmo tamanho eu passo para a comparação dos binário

Vamos agora programar:

O interessante deste projeto é que vamos estudar as classes e métodos do Namespace System.IO, biblioteca responsável por permitir trabalhar com arquivos físicos ou em memória, diretórios de arquivos…lendo, criando e apagando.

Para carregar um arquivo em memória no C# devemos instanciar a classe FileInfo, conforme exemplo:

FileInfo Finfo = new FileInfo("C:\\Temp\\Arquivo.jpg");

Através dela podemos, ler, deletar, mover, copiar um arquivo

Para carregar um diretório em memória, e capturar o arquivos que nele contém, utilizamos a classe DirectoryInfo, conforme exemplo:

DirectoryInfo dInfo = new DirectoryInfo("c:\\temp");
foreach (FileInfo fInfo in dInfo.GetFiles("*.jpg"))
{
// Faz alguma coisa com o arquivo
}

com isto montamos dois métodos principais, sendo o primeiro o responsável por comparar o tamanho dos arquivos:


private bool validaPorTamanho(FileInfo fInfoComparador, FileInfo fInfoComparado)
{
return fInfoComparador.Length.Equals(fInfoComparado.Length);
}

O segundo método é o principal , responsável por comparar os arquivos através do seu array de bytes


private bool validaPorConteudo(FileInfo afInfoComparador, FileInfo afInfoComparado)
{
// Indicador booleano de igualdade dos arquivos
bool abolArquivosIguais = true;

// Instância do Arquivo original

StreamReader lstremArquivoComparador = null;

// Instância do Arquivo a ser comparado

StreamReader lstremArquivoComparado = null;

// Array de Bytes do arquivo oringal

byte[] larrArquivoComparador = null;

// Array de Bytes do arquivo comparado

byte[] larrArquivoComparado = null;

try
{
//  Carrega os arquivos nas streams

lstremArquivoComparador = new StreamReader(afInfoComparador.FullName);

lstremArquivoComparado = new StreamReader(afInfoComparado.FullName);

/*Verifica se as stream não estão vázias
(pode acontecer caso o arquivo já tenha sido deletado)*/

if (lstremArquivoComparador != null && lstremArquivoComparado != null)
{
// Carrega os arrays de bytes
larrArquivoComparador = new byte[(int)lstremArquivoComparador.BaseStream.Length];
lstremArquivoComparador.BaseStream.Read(larrArquivoComparador, 0, (int)lstremArquivoComparador.BaseStream.Length);

larrArquivoComparado = new byte[(int)lstremArquivoComparado.BaseStream.Length];
lstremArquivoComparado.BaseStream.Read(larrArquivoComparado, 0, (int)lstremArquivoComparado.BaseStream.Length);

// Verifica novamente se os arrays tem o mesmo tamanho
if (larrArquivoComparador.Length == larrArquivoComparado.Length)
{
abolArquivosIguais = true;

// Realiza a comparação lendo binário a binário dos arquivos
for (int i = 0; i < larrArquivoComparador.Length; i++)
{
if (larrArquivoComparador[i] != larrArquivoComparado[i])
abolArquivosIguais = false;
}
}
else
{
abolArquivosIguais = false;
}
}
else { abolArquivosIguais = false; }
}
catch (Exception)
{
}
finally
{
// Ao final da execução, libera os arquivos
if (lstremArquivoComparador != null)
lstremArquivoComparador.Dispose();

if (lstremArquivoComparado != null)
lstremArquivoComparado.Dispose();
}
return abolArquivosIguais;
}

e agora vamos criar o método que sequenciar as comparações:


private bool comparaArquivos(FileInfo afInfoComparador, FileInfo afInfoComparado)
{
bool abolArquivosIguais = false;
abolArquivosIguais = this.validaPorTamanho(afInfoComparador, afInfoComparado);

if (abolArquivosIguais)
abolArquivosIguais = this.validaPorConteudo(afInfoComparador, afInfoComparado);

return abolArquivosIguais;

}

Agora que temos nossos métodos principais, vamos estrutura nosso projeto, como não precisamos de uma interface vamos fazer uma Console Application. Segue a estrutura básica:

Sem Título-2Pronto, temos o nosso projeto pronto 🙂

A primeira verificação de arquivos repetidos da minha máquina deu quase 2GB de imagens e 5 GB de mp3 🙂

Para baixar o código fonte, segue o link:

https://www.dropbox.com/s/vyztzsl7qr1tpzp/PhotoOrganizer.rar

Lembrando que o código foi compilado em .Net Framework 4.5 no Visual Studio 2013

 

Publicado em .Net Framework 4.5, C#, LINQ, Orientação a Objeto, System.IO, VS2013 | Marcado com , , , , , , | Deixe um comentário

Exemplo de Aplicação Introdução ao ASP.NET – Módulo 06 – Validando entrada do usuário

Boa tarde Segue o exemplo da Módulo 06, “Validando entrada do usuário”, seguindo tudo que foi visto na sala de aula e no slide da aula em anexo:

  1. O que é validação de usuário
  2. Validação Client-Side e Server Side
  3. Overview dos controles de validação ASP.NET
  4. Controles básicos para validação
    1. #RequiredFieldValidator
    2. #CompareValidator
    3. #RangeValidator
  5. Controle #RegularExpressionValidator
  6. Controle #CustomValidator

Modulo6

O exemplo está disponível em: https://www.dropbox.com/s/cvoxm6vq44yjmbf/FFB.Modulo6.rar

A aplicação está implementada com os seguintes requisitos:

  • Visual Studio 2010+
  • Microsoft .Net Framework 4.0
  • Jquery

Qualquer dúvida, estou aqui disposto a ajudar 🙂 Slides: Modulo6 Obrigado

Publicado em ASP.NET, C#, MasterPage, Orientação a Objeto, Validação | Deixe um comentário

Exemplo de Aplicação Introdução ao ASP.NET – Módulo 05 – MasterPage e WebUserControl

Bom dia

Segue exemplo da aula de número 05, #MasterPage e #WebUserControls, seguindo tudo que foi visto na sala de aula e no slide da aula em anexo:

  1. O que é MasterPage
  2. Como Criar uma página com Master Page
  3. Nested MasterPage (Aninhadas)
  4. Master Type
  5. Troca dinâmica de Master Page em tempo de execução

O exemplo está disponível no link

https://www.dropbox.com/s/g8meqil5wvhhc25/FFB.Modulo5.rar

A aplicação está implementada com os seguintes requisitos:

  • Visual Studio 2010+
  • Microsoft .Net Framework 4.0
  • Jquery
  • Bootstrap

A mesma contém quatro MasterPages de exemplo:

  1. Site.Master: Default do VS2010
  2. Bootstrap.Master: Master Page utilizando a framework de interface ao usuário (UI) #Bootstrap
  3. Layout.Master: Cópia da Site.Master mudando apenas o CSS
  4. NestedMasterPage.master: MasterPage aninhada com a Site.Master

O exemplo poderá alternar dinamicamente entre as Master Page 1 e 2, para isto basta clicar no nome de cada uma delas no Menu Superior.

A demonstração do Master Type está na parte inferior de cada Master Page, informando o nome da página que está sendo acessada.

 

Qualquer dúvida, estou aqui disposto a ajudar 🙂

Slides:  Módulo 05 – Introdução a MasterPage e WebUserControl

obrigado

Publicado em ASP.NET, Bootstrap, C#, MasterPage, Orientação a Objeto | 1 Comentário

Exemplo de Aplicação Introdução ao ASP.NET – Módulo 04

Boa noite, Conforme prometido em sala de aula, segue os exemplos do que foi visto em sala neste módulo e também o PPT do Módulo 04

O que contempla o exemplo:

  • Aplicação ASP.NET utilizando C# e .Net Framework 4.0
  • A masterPage está utilizando a biblioteca BootStrap, para exemplo de como utilizar arquivos Javascript na página
  • 4 exemplos que demonstram como utilizar e executar Handle Client-Side, Eventos do lado Cliente utilizando
    • Javascript
    • Jquery
  • Projeto Class Library com classes (entidades) de exemplo demonstrando entidades
    • Uso de de atributos privados e Propriedades de encapsulamento
    • Entidades com Propriedades Auto-Implementada (get;set;)
  • Exemplo completo (Interface, Separação de Camada, Funcional) de uma aplicação WEB que persiste os dados do cliente em um arquivo XML (Serialização) .

Download do exemplo: https://www.dropbox.com/s/7y616f6ml3rh7ey/FFB.Modulo4.rar

Slide: Modulo4

 

Publicado em ASP.NET, C#, Orientação a Objeto | Deixe um comentário

Recuperando dados com Microsoft Dynamics CRM 2011

Olá a todos,

iniciando aqui uma série de pequenos posts sobre Microsoft Dynamics CRM 2011. O primeiro será sobre recuperação de dados utilizando o SDK disponibilizado pela microsoft no endereço:

http://www.microsoft.com/en-us/download/details.aspx?id=24004

A primeira forma de consultar é a que considero mais simples de todas, dado uma entidade que desejo recuperar através de seu identificador iremos usar a abordagem Late-Bound (para maior entendimento, sugiro este artigo http://msdn.microsoft.com/en-us/library/gg327971.aspx) para se conectar ao servidor do CRM e recuperar a entidade.

Nossa missão, recuperar o Número do Ticket (TicketNumber) da Ocorrência (Incident) cujo identificador único é “FE69CAF4-1693-E211-B951-00155D01C805”

Para começar, precisamos adicionar a referência ao SDK do CRM ao nosso projeto, para isto devemos referenciar a biblioteca “sdk\bin\microsoft.xrm.sdk.dll”.  Aproveitando também devermos adicionar as bibliotecas:

  • System.Runtime.Serialization
  • System.ServiceModel

A nossa classe de consulta deverá conter as seguintes referências no topo:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.ServiceModel.Description;

Abaixo segue o Código Fonte que realiza a conexão ao servidor CRM através do Organization.SVC (para pegar o endereço do serviço: Na tela do CRM, clicar em Configurações > Personalizações > Recursos do Desenvolvedor  > Serviço da Organização).

//Uri da organição

Uri clientUri = new Uri("http://crm/My/XRMServices/2011/Organization.svc");

//Credenciais para conexão
ClientCredentials clientCredentials = new ClientCredentials();

clientCredentials = new ClientCredentials();

clientCredentials.UserName.UserName = "****\\olavoneto";

clientCredentials.UserName.Password = "******";

//Identificador da ocorrência

Guid incidentId = new Guid("FE69CAF4-1693-E211-B951-00155D01C805");

//Abrindo a conexão ao Serviço

using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(clientUri, null, clientCredentials, null))

{

//Instânciação da entidade, definido o tipo da mesma

Entity entity = new Entity("incident");

//Instânciação do ColumnSet, informando que desejamos todas as colunas no resultado

ColumnSet columnSet = new ColumnSet(true);

//Recuperação da entidade

entity = serviceProxy.Retrieve("incident",incidentId,columnSet);

//Capturando o Ticket da ocorrência

string ticketNumber = entity["ticketnumber"].ToString();

}

Assim, desta forma simples conseguimos recuperar entidades do CRM através de seu identificador. Para o próximo post faremos consultas recuperando várias entidades ao mesmo tempo.

Publicado em C#, Dynamics CRM | Marcado com , , , , | Deixe um comentário

Controlando abertura de janelas com Windows Forms

Uma das questões que tenho visto muito no Fórum MSDN é que vários usuários tem dúvidas é de como controlar corretamente a abertura de janelas em suas aplicações Windows Forms. Claro, abrir uma janela é algo bem simples, mas falo em gerenciar o ciclo de vidas das janelas, permitindo que somente uma delas fique possa ser aberta e também capturando valores das janelas abertas.

1. Form MDI

Vamos ao primeiro exemplo, uma janela MDI(multiple document interface) que irá comportar todas as janelas da nossa aplicação e controlar a abertura das janelas de modo que somente uma instância de cada janela possa existir durante a execução da aplicação.

Para começar, vamos criar um projeto Windows Forms, por padrão o Visual Studio irá criar um Form de nome Form1.cs, Ele será nossa janela MDI, para isso vamos alterar a propriedade do Form IsMdiContainer p/ TRUE conforme a imagem abaixo:

Agora iremos criar um novo Form. Para o exemplo, irei criar uma janela com um formulário para cadastrar usuários, algo bem simples, pedindo apenas o nome  e a data de nascimento do usuário, segue abaixo o layout da janela.

Criado a janela que deverá ser aberta, agora é será definido como isto será feito. Para o exemplo vamos criar um pequeno menu utilizando o controle MenuStrip, definindo apenas um Item e um Sub-Item.

Agora vamos digitar o código que irá controlar a abertura do nosso form, deixando que apenas uma instância da janela exista durante a execução e eliminando a janela da memória quando ela não for mais necessária. Se você prestar atenção essa descrição lembra uma Pattern (Padrão de projeto) conhecido como Singleton. Basicamente utilizaremos o principio deste padrão no nosso código, conforme pode ser visto no código abaixo:

/// <summary>
/// Declaração da váriavel do Form
/// </summary>
private CadUsu frmCadUsu = null;

/// <summary>
/// Abertura da Janela de Cadastro de Usuário
/// Baseado no pattern Singleton
/// Verificando se a janela já existe
/// Instânciando o form caso ela não exista
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void usuárToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (frmCadUsu == null)
 {
   frmCadUsu = new CadUsu();
   frmCadUsu.MdiParent = this;
   frmCadUsu.Disposed += new EventHandler(frmCadUsu_Disposed);
   frmCadUsu.Show();
 }
}
/// <summary>
/// Evento que será disparado quando a janela for fechada
/// Eliminando o objeto da memória
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void frmCadUsu_Disposed(object sender, EventArgs e)
{
   frmCadUsu = null;
}

Veja que o código é bem simples, basicamente controlamos a variável que recebe a janela em questão. Se ela for nula, instanciamos a janela, informando qual o FormMdi Pai e criando o evento que será disparado quando a janela for fechada. Este evento limpa a variável da janela, para que então, ela possa ser aberta novamente.

2. Recuperando um valor digitado no Form aberto
Agora que criamos o Form e já estamos controlando a sua criação, vamos retornar um valor do Form Instanciado. Para isso, vamos inserir o seguinte código na nossa janela CadUsu:

/// <summary>
/// Retorna o valor digitado no controle txtNome
/// </summary>
public string NomeUsuario
{
   get { return txtNome.Text; }
}

/// <summary>
/// Retorna a data selecionada no DtpDatNasc
/// </summary>
public DateTime DataNascimento
{
   get { return dtpDatNasc.Value; }
}

private void btnFechar_Click(object sender, EventArgs e)
{
   this.Close();
}

Para finalizar nosso pequeno exemplo, vamos capturar os valores quando a janela for fechada. Para isso teremos que utilizar outro evento da janela aberta, o FormClosing. Este evento é disparado durante o fechamento da janela, mas antes do dispose dos controles em memória. O código ficará assim:


/// <summary>
/// Declaração da váriavel do Form
/// </summary>
private CadUsu frmCadUsu = null;

/// <summary>
/// Abertura da Janela de Cadastro de Usuário
/// Baseado no pattern Singleton
/// Verificando se a janela já existe
/// Instânciando o form caso ela não exista
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void usuárToolStripMenuItem_Click(object sender, EventArgs e)
{
  if (frmCadUsu == null)
  {
      frmCadUsu = new CadUsu();
      frmCadUsu.MdiParent = this;
      frmCadUsu.FormClosing += new FormClosingEventHandler(frmCadUsu_FormClosing);
      frmCadUsu.Disposed += new EventHandler(frmCadUsu_Disposed);
      frmCadUsu.Show();
   }
}

/// <summary>
/// Evento que será disparado durante o fechamento da janela
/// aonde iremos capturar os valores das propriedades
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void frmCadUsu_FormClosing(object sender, FormClosingEventArgs e)
{
   //Verifica se algum valor foi digitado
   if (frmCadUsu.NomeUsuario.Length > 0)
      this.mostraDadosUsuarios(frmCadUsu.NomeUsuario,
   frmCadUsu.DataNascimento);
}

/// <summary>
/// Mostra os dados do usuário
/// </summary>
/// <param name="p"></param>
/// <param name="dateTime"></param>
private void mostraDadosUsuarios(string _Nome, DateTime _DatNasc)
{
   int idadeUsu = DateTime.Now.Subtract(_DatNasc).Days / 360;
   MessageBox.Show(string.Format("Olá {0}, \r\n Você tem: {1} Anos", _Nome, idadeUsu));
}

/// <summary>
/// Evento que será disparado quando a janela for fechada
/// Eliminando o objeto da memória
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void frmCadUsu_Disposed(object sender, EventArgs e)
{
   frmCadUsu = null;
}

Ao final, teremos uma tela mostrando o resultado dos dados digitados:

Bom, é isso. Eu sei que não foi um post de assuntos novos, nem nada de muito complicado, mas espero que ele ajude a quem precisa 🙂


Publicado em C#, Windows Forms | 1 Comentário

Tipos Complexos com Code First

Olá pessoal, vamos dar continuidade sobre os posts do Code First, agora falando um pouco sobre Tipos Complexos (Complex Types).

1. Tipos Complexos

Tipos Complexos (Complex Types) é uma funcionalidade integrada do ADO.Net Entity Framework 4.1 que permite a composição de várias Classes de Domínio em uma única Tabela a ser persistida no banco de dadoss, por exemplo:, vejam a Figura 1:

Figura 1. Classes de Domínio

Conceito: Granularidade define o nível de detalhamento de uma aplicação, ou seja, Granularidade Grossa: indica que existirão poucas classes com uma grande quantidade de detalhes (Poucos grãos, porem grossos). Granularidade Fina: consiste em várias classes com pouco detalhamento (no nosso caso, propriedades).

O Diagrama acima mostra um alto nível de detalhamento no nosso conjunto de classes que compõem a entidade Cliente. Explodimos a classe Cliente em um conjunto de classes, agrupando o código que poderá se repetir em uma classe única e referenciando em uma propriedade, dessa forma nosso código se torna mais reutilizável e entendível.

Um detalhe importante é que a classe que irá compor um Complex Type não poderá ter identidade (por exemplo, TelefoneId). Segue abaixo na Listagem 1 o código que compõe nosso conjunto de classes.

using System;

namespace Entities
{
    public class Cliente
    {
        public int ClienteId { get; set; }
        public string Nome { get; set; }
        public Telefone TelefoneResidencial { get; set; }
        public Telefone TelefoneCelular { get; set; }
        public Telefone TelefoneTrabalho { get; set; }
        public Endereco Endereco { get; set; }
    }

    public class Telefone
    {
        public int CodigoArea { get; set; }
        public Int32 Numero { get; set; }
    }

    public class Endereco
    {
        public string Rua { get; set; }
        public int Numero { get; set; }
        public string Complemento { get; set; }
        public Int32 CEP { get; set; }
        public string Bairro { get; set; }
    }

}

Listagem 1. Código que compõe a Tipo Complexo Cliente

2.  Mapeando o Tipo Complexo

O mapeamento do Tipo Complexo é feito de forma similar a de qualquer outra classe que deverá ser persistida utilizando o Code First, Através do DbSet é informado a classe principal e definido seu nome, conforme mostra a Listagem 2.

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace Entities
{
    public class MyContext:DbContext
    {
        public DbSet<Cliente> Clientes { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            base.OnModelCreating(modelBuilder);
        }
    }
}

3. Criando um Dado

Agora com o Tipo criado e  Mapeado, vamos criar o primeiro cliente de forma ao Code First mapear nosso Conjunto de Classes e criar os objetos necessários a serem persistidos no banco de dados (para maiores detalhes, ver postes anteriores).  Para isso vamos instanciar nossa classe de contexto, criar um novo banco de dados, depois criar um novo cliente e então salvar os dados. Segue código na Listagem 3.

using System;
using Entities;
namespace CodeFirstConsole
{
    class Program
    {
        static void Main(string[] args)
        {

            using (Entities.MyContext MyContext = new MyContext())
            {
                if (MyContext.Database.Exists())
                {
                    Console.WriteLine("BD existente, deletando...");
                    MyContext.Database.Delete();
                }
                Console.WriteLine("Criando BD");
                MyContext.Database.Create();

                MyContext.Clientes.Add(new Cliente()
                {
                    Nome = "Olavo Oliveira Neto",
                    Endereco = new Endereco() { Rua = "XXX", Bairro = "YYY", CEP = 00000000, Numero = 1 },
                    TelefoneCelular = new Telefone() { CodigoArea = 85, Numero = 123456789 },
                    TelefoneResidencial = new Telefone() { CodigoArea = 85, Numero = 987654321 },
                    TelefoneTrabalho = new Telefone() { CodigoArea = 85, Numero = 789654123 }
                });

                MyContext.SaveChanges();
                Console.WriteLine("Processo Terminando, Pressione qualquer tecla para fechar.");
                Console.Read();

            }
        }
    }
}

Após a execução do código, poderemos ver no banco de dados que foi criado uma tabela com a seguinte disposição:

Figura 2. Classe Cliente

Na Figura 2, é possivel ver que foi criado uma única tabela, que consiste em todas as classes do nosso Tipo Complexo Cliente.

Bom, isso foi só um pouco mais sobre Code First e Tipos Complexos.

Publicado em Code First, Entity Framework, LINQ | Deixe um comentário

Entity Framework Code First

Olá pessoal, quanto tempo em?

Voltando aqui para falar um pouco sobre o Code First, uma nova feature do Microsoft ADO.Net Entity Framework 4.1, que poderá ser baixado do site: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8363 ou de outras formas que eu irei falar mais para frente 🙂

Code First, O que é ?

  1. A tecnologia de Mapeamento Objeto-Relacional(O/RM) da Microsoft fornece uma série de abordagens para o desenvolvimento de aplicações, ou seja, resolver um dos questionamentos do que virá primeiro, o banco de dados ou a aplicação. Para isto o Entity Framework nós fornece três possibilidades:
  • Database First: A partir de um banco de dados já existente, o Entity Framework irá realizar o mapeamento das tabelas e criar o as entidades correspondentes.
  • Model First: Introduzido na Framework 4.0, o Model First permite que seja criado primeiramente o mapeamento relacional da aplicação através da ferramenta gráfica do Visual Studio para que então seja criado o banco de dados da aplicação.
  • Code First: Eis nosso foco, a nova feature da Entity Framework que permite que através das classes da aplicação que representam as entidades de negócio seja possível manipular dados sem que um banco de dados já exista. Ou seja, através de uma aplicação nova ou já existente que contem uma série de classes POCO (Plain Old CLR Objects, leia mais em: http://blogs.msdn.com/b/efdesign/archive/2008/06/24/initial-poco-design-1-pager.aspx) é possível deixar para a Framework o trabalho de criar o banco, tabelas e mapeamento baseado na estrutura de classes da sua aplicação, incrível não é
Exemplo:
Inicialmente, vamos criar uma aplicação simples, somente para demonstrar com instalar e utilizar o Code First integrado ao Entity Framework, Para instalar o Entity Framework 4.1 e referenciar o projeto, irei utilizar o gerenciador de pacote NuGet (http://nuget.codeplex.com/)
Para isso, vamos criar um um Projeto Web Vazio, com o nome de MyCodeFirst, conforme a Figura 1

Criando Projeto MyCodeFirst

Definindo as classes POCO

Agora com o projeto criado, vamos criar nossas entidades Poco, para esse primeiro exemplo, vamos criar um conjunto de classes que armazenem dados sobre carros, motos e caminhões. Para isto, teremos as classe Marca, Modelo, uma classe abstrata Veiculo e três classes que à herdam. Segue na Figura 2 o diagrama de classe da nossa aplicação:

Diagrama de Classe POCO

Segue abaixo na listagem 1, o código de criação das entidades:

namespace MyCodeFirst
{
    public class Marca
    {
        public int MarcaId { get; set; }
        public string Nome { get; set; }
    }
    public class Modelo
    {
        public int ModeloId { get; set; }
        public string Nome { get; set; }
        public Marca Marca { get; set; }
    }
   public class Carro
    {
        public int CarroId { get; set; }
        public Modelo Modelo { get; set; }
        public int AnoFabricacao { get; set; }
        public int AnoModelo { get; set; }
        public int QtdRodas { get; set; }
        public string Cor { get; set; }
    }
}

Referenciando o Entity Framework 4.1 

Nossas classes já estão criadas, agora vamos adicionar a referência do Entity Framework 4.1 ao nosso projeto, para isto, vamos clicar com o botão direito sobre o projeto e então clicar em Manage NuGet Packages, Conforme a Figura 3

Nova Opção para Adicionar Referências

Na tela do Manage NuGet Packages, espere ele terminar de listar todos os pacotes, procure por EFCodeFirst e então clique em Install. O download da biblioteca será feito e você deverá confirmar a licença de utilização. Este processo poderá demorar um pouco. Por fim, você verá que foi baixado e instalado em sua aplicação a referência ao Entity Framework 4.1.

Tela de Seleção do NuGet Package

Criando a Classe de Contexto

Para quem já trabalhou com Entity Framework, utilizando um arquivo de mapeamento, sabe que o contexto é a classe que, além de várias outras funções, é responsável por gerenciar as conexões com o banco de dados, servir de proxy para realização de consultas e alteração e inserção de dados fazendo a montagem das entidades, etc.

Para o Code First, a classe de contexto é a classe que e irá informar para a aplicação, o que será mapeado para o banco de dados, qual e como acessar este banco de dados e quais ações deverão ser feitas para realizar este mapeamento (inclusive criar o próprio banco de dados) .

Para criar-mos nossa classe de contexto, devemos criar uma nova classe que herde a classe DbContext que encontra-se no namespace System.Data.Entity.

Agora que criamos a classe de contexto vamos informar o que será mapeado, isto deverá ser feito criando uma propriedade do tipo DbSet e informando via parâmetro genérico as entidades que serão mapeada. Veja abaixo na Listagem 2 como a classe ficará:

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace MyCodeFirst
{
    public class AutomoveisContext:DbContext
    {
        public DbSet<Carro> Carros { get; set; }
        public DbSet<Marca> Marcas { get; set; }
        public DbSet<Modelo> Modelos { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }
}
A sobreposição do método OnModelCreating é uma forma de poder controlar alguns detalhes que  envolvem a criação do modelo no banco de dados e do mapamento, por exemplo inibir a pluralização do nome das tabelas.
Definindo a String de Conexão
Agora que já temos a classe de contexto pronta, vamos informar a aplicação, como ela irá se comunicar com o banco de dados.
Este passo não é verdadeiramente necessário caso a instalação do Visual Studio tenha sido a default, instalando também o Microsoft SQL Server 2005/2008 Express em uma instância nomeada de SqlExpress. O CodeFirst irá detectar que nenhuma string de conexão foi informada e irá criar uma conexão ao seu banco de dados, criando um banco com o nome da classe de contexto.
Caso esse não seja o caso, ou você deseje controlar isso, basta adicionar ao web.config uma string de conexão com o mesmo nome da classe de contexto, conforme exemplo abaixo na Listagem 3:

<connectionStrings>
  <add name ="AutomoveisContext"
       connectionString="Data Source=.\sqlexpress;Initial Catalog=AutomoveisDB;Integrated Security=True;MultipleActiveResultSets=True"
       providerName="System.Data.sqlClient"/>
</connectionStrings>

Testando a Aplicação

Agora que já temos tudo pronto para executar nossa aplicação, vamos criar uma página web que irá alimentar os dados (neste caso, irei fazer isso diretamente no código, sem interface com o usuário). O legal do Code First é que até agora nós não fizemos nada com relação a banco de dados e mapeamento com EDMX, mas, já está tudo pronto para funcionar 🙂

Segue abaixo na Listagem 4 o código da página WebForm1.aspx:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyCodeFirst
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        AutomoveisContext automoveisDB = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            automoveisDB = new AutomoveisContext();

            if (!IsPostBack)
            {
                this.criarBanco();
                this.registraMarcas();
                this.registraModelos();
                this.registraCarros();
            }
        }
        private void registraMarcas()
        {
            automoveisDB.Marcas.Add(new Marca() { Nome = "Chevrolet" });
            automoveisDB.Marcas.Add(new Marca() { Nome = "Honda" });
            automoveisDB.Marcas.Add(new Marca() { Nome = "Fiat" });
            automoveisDB.Marcas.Add(new Marca() { Nome = "Renault" });
            automoveisDB.SaveChanges();
        }

        private void registraModelos()
        {
            //Para Chevrolet
            Marca marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Chevrolet"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Camaro" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Agile" });
            //Para Honda
            marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Honda"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Fit" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Civiv" });
            //Para Honda
            marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Fiat"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "500" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Punto" });
            //Para Renault
            marca = automoveisDB.Marcas.Single(c => c.Nome.Equals("Renault"));
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Clio" });
            automoveisDB.Modelos.Add(new Modelo() { Marca = marca, Nome = "Sandero" });
            automoveisDB.SaveChanges();
        }

        private void registraCarros()
        {
            //Camaro
            Modelo modelo = automoveisDB.Modelos.Single(c => c.Nome.Equals("Camaro"));
            automoveisDB.Carros.Add(new Carro()
                {
                    AnoFabricacao = 2011,
                    AnoModelo = 2011,
                    Cor = "Preto",
                    Modelo = modelo,
                });

            //Fit
            modelo = automoveisDB.Modelos.Single(c => c.Nome.Equals("Fit"));
            automoveisDB.Carros.Add(new Carro()
            {
                AnoFabricacao = 2010,
                AnoModelo = 2010,
                Cor = "Prata",
                Modelo = modelo,
            });

            //Sandero
            modelo = automoveisDB.Modelos.Single(c => c.Nome.Equals("Fit"));
            automoveisDB.Carros.Add(new Carro()
            {
                AnoFabricacao = 2010,
                AnoModelo = 2011,
                Cor = "Verde",
                Modelo = modelo,
            });
            automoveisDB.SaveChanges();
        }

        /// <summary>
        /// Método responsável por verificar se o banco de dados já existe
        /// se Sim = Deletar banco e Criá-lo novamente
        /// se Não, Criar banco
        /// </summary>
        private void criarBanco()
        {
            //Verifica
            if (automoveisDB.Database.Exists())
                automoveisDB.Database.Delete();
            automoveisDB.Database.Create();
        }
    }
}

Vejam que o código acima é simples e segue um pequeno fluxo:

1. Ele irá verificar se o banco de dados já está registrado no servidor informado. Caso sim, o code first irá deletar o banco e criá-lo novamente. Essa ação,  claro é bem prática para ambiente de desenvolvimento.
também é possivel utilizar o método CreateIfNotExists(); que como o próprio nome diz, ele somente irá criar o banco de dados caso ele não exista. Ambos os métodos retornam booleano informando se foi ou não possivel criar o banco.

2. Registra as marcas

3. Registra os modelos

4. Registra os carros

Depois da execução da página, é possivel observar no servidor de BD a criação do banco com o nome de AutomoveisDB e 4 tabelas. três delas nós que criamos e a outra (EdmMetadata) é uma tabela default do Code First responsável por armazenar um Hash do modelo existente. Esse Hash é utilizado para verificar se o modelo atual ainda é válido para banco criado, ou seja, se for criado um campo novo em alguma entidade, ou até mesmo uma nova entidade, os hashs não coincidirão e a utilização não será possivel.

Bom, espero que tenha dado pra entender um pouco do Code First, essa nova funcionalidade do Entity Framework que veio pra ajudar e muito os desenvolvedores.

Até a próxima

Publicado em C#, Code First, Entity Framework, LINQ | Deixe um comentário

Entity SQL

E ai pessoal, já faz um tempinho que eu não falo de LINQ então vou falar rapidamente sobre uma funcionalidade do Entity Framework que eu considero como essencial, mas que poucos desenvolvedores ainda conhecem. Estou falando do Entity SQL. Uma linguagem similar ao conhecido Transact-SQL (T-SQL) voltada para consultas às entidades mapeadas pelo Entity Framework direto no modelo conceitual.

Pode até parecer estranho que se possa utilizar uma linguagem SQL para consultas ao Entity Framework já que ele realiza o Mapeamento Objeto Relacional visando diminuir a impedância da aplicação. Mas entendamos que quando ele foi desenhado o LINQ já existia e foi apenas incorporado ao seu funcionando, mas que devido a sua gama de funções e facilidades de uso se tornou seu principal meio de consulta.

A principal vantagem em utilizar o Entity SQL é a possibilidade de realizar consultas que não são possíveis ou que se tornam muito complicadas com o LINQ to Entities, por exemplo:

  • Conversões dentro da query (o LINQ to Entities não suporta, por exemplo, que você utilize códigos como int.parse() dentro das consultas: o erro abaixo será mostrado em tempo de execução: LINQ to Entities does not recognize the method ‘Int32 Parse(System.String)’ method, and this method cannot be translated into a store expression.
  • Consultas dinâmicas que sua query seja montada durante a execução. Já vi códigos em LINQ gigantescos ou vários códigos LINQ um abaixo do outro dentro de vários IF-ELSE para conseguir fazer isto.
  • Melhor para fazer filtros e ordenações de forma dinâmica.

1 – Consultas Básicas

Para começar, entenda que o mapeamento ainda é necessário e que tudo acontece passando pelo nosso Objeto de Contexto.

As consultas poderão ser realizas utilizando o objeto de contexto, por exemplo:


//Listandos os produtos que tem valor maior que 1000 e menor igual a 3000
//Para este caso o uso do it. é obrigatorio, sem ele o campo não será encontrado
List<Produto> lstProdutos = ex.Produto.Where("it.valor > 1000 && it.valor <=3000").ToList();

Ou utilizando o ObjectQuery, informando qual a entidade que será consultada, por exemplo:


//Instanciando a classe ObjectQuery passamos como parâmetros a consulta e o objeto de contexto
//A Consulta se assemelha muito a um SQL tradicional
ObjectQuery<Produto> queryProdutos = new ObjectQuery<Produto>( "select VALUE p from Produto as p where p.valor >2000", ex);
lstProdutos = queryProdutos.ToList();

Sobre a consulta acima, notem que:

–      O VALUE faz o papel de * do nosso conhecido e temido SELECT * FROM. Caso se tente colocar o * mesmo assim, o seguinte erro será mostrado em tempo de execução: he query syntax is not valid. Near term ‘*’

–      Apesar de extensa, essa consulta não é obrigatória,ela pode ser substituída apenas pelo nome da entidade.

2 – Consultas dinâmicas, Ordenação e Filtros

O aspecto mais legal e que mais recomendo para a utilização do Entity SQL é justamente para aplicação de filtros e ordenadores. O LINQ mantém isso muito amarrado, não é possível por exemplo eu ordenar um consulta a minha entidades produtos alternando a ordenação entre o valor do produto ou o nome dele.  Para casos assim eu já vi a seguinte solução:


exampleEntities ex = new exampleEntities();
List<Produto> lstProdutos = null;
string ordenador = "";

 //Valor selecionado pelo usuário: CPF
ordenador = "Nome";
 switch (ordenador)
{
case "Id": lstProdutos = ex.Produto.OrderBy(c => c.Id).ToList();
break;
case "Nome": lstProdutos = ex.Produto.OrderBy(c => c.Nome).ToList();
break;
case "Valor": lstProdutos = ex.Produto.OrderBy(c => c.Valor).ToList();
break;
}

Vejam que não é uma solução muito elegante e bastante repetitiva, sem falar que qualquer nova coluna na tabela da entidade obrigará a mudanças no código.

Sendo assim, vamos refazer o exemplo utilizando o Entity SQL a nosso favor:


exampleEntities ex = new exampleEntities();
List<Produto> lstProdutos = null;
string ordenador = "";
 //Valor selecionado pelo usuário: Valor
ordenador = "Valor";

//Desta vez irei passar somente o nome da entidade no parâmetro de consulta
ObjectQuery<Produto> queryProdutos = new ObjectQuery<Produto>("Produto", ex);

 //chamamos o método OrdeyBy passando uma string que nada mais é do que
//a concatenação do it. e o nome da coluna desejada para ordenação
lstProdutos = queryProdutos.OrderBy(string.Format("it.{0}", ordenador)).ToList();

Ta bom por enquanto. Depois eu posto mais algumas coisas legais que se pode fazer com Entity SQL!!


Publicado em LINQ | 1 Comentário