quinta-feira, 4 de abril de 2013

Linq - Visão básica


Trabalhar com Linq é sensacional.

Antigamente ao se trabalhar com banco de dados e objetos era um pouco complicado. Pois tínhamos que conhecer o banco de dados, montar a query, executar e percorrer todos os resultados para preencher o objeto correspondente.

No linq isso é diferente. Eu tenho o banco de dados mapeado e eu já crio os objetos para cada item do banco. Por exemplo: Tabela, View e Procedure.

No exemplo a seguir vou trabalhar com apenas uma tabela, chamada de usuario. Veja a estrutura criada no Microsoft SQL Server:   
No Visual Studio, clique com o botão direito do mouse sobre o projeto e no menu Add-> New Item. Como no exemplo abaixo:


A janela a seguir será exibida, selecione o item “LINQ to SQL Classes” dentro de Data e dê um nome ao item, no meu caso Banco.bdml.



Agora será necessário mapear os itens do banco de dados. Para isso existem duas maneiras: Manual e utilizando assistente.

Fazendo da forma manual o código fica mais limpo e a manutenção fica fácil e é mais rápida. Porém, se você tem um banco de dados com um número expressivo de tabelas, é mais fácil fazer com o assistente. Vou demonstrar os dois, começando pelo manual.

Mapeamento Manual
Na guia “Solution Explorer” abra o arquivo Banco.designer.cs



A primeira coisa a se fazer é criar a Classe de contexto que irá representar o banco de dados.

//Nome do banco de dados
[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="Testes")]
public partial class Banco : System.Data.Linq.DataContext
{

private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();

        //Connection String - Definida no app.config – não se esqueça de criar a conexão no app.config,
        public Banco() :
base(global::ExemploAplicacao.Properties.Settings.Default.TestesConnectionString, mappingSource)   
{
}

//Retorna relação de usuários do banco de dados
public System.Data.Linq.Table<usuario> usuarios
{
get
{
return GetTable<usuario>();
}
}

}


Após criar a Classe de contexto temos que mapear a tabela usuário, criada anteriormente.
//Classe usuario e Ligação com a tabela usuario
       [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.usuario")]
       public partial class usuario : INotifyPropertyChanging, INotifyPropertyChanged
       {           
             private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);      
        //Atributos que representarão os campos da minha tabela.
             private System.Guid _id;         
             private string _nome;
        private string _email;

        //construtor padrão do objeto Usuario
             public usuario()
             {     
             }
             //Mapeamento da propriedade id com o campo id do banco de dados
             [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_id", DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true)]
             public System.Guid id
             {
                    get
                    {
                           return _id;
                    }
                    set
                    {
                           if ((_id != value))
                           {     
                                  _id = value;                           
                           }
                    }
             }
        //Mapeamento da propriedade nome com o campo nome do banco de dados
             [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_nome", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
             public string nome
             {
                    get
                    {
                           return _nome;
                    }
                    set
                    {
                           if ((_nome != value))
                           {                                
                                  _nome = value;                                
                           }
                    }
             }

        //Mapeamento da propriedade nome com o campo nome do banco de dados
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_email", DbType = "VarChar(255) NULL", CanBeNull = false)]
        public string email
        {
            get
            {
                return _email;
            }
            set
            {
                if ((_email != value))
                {
                    _email = value;
                }
            }
        }

            
             public event PropertyChangingEventHandler PropertyChanging;       
             public event PropertyChangedEventHandler PropertyChanged;         
             protected virtual void SendPropertyChanging()
             {
                    if ((this.PropertyChanging != null))
                    {
                           this.PropertyChanging(this, emptyChangingEventArgs);
                    }
             }
            
             protected virtual void SendPropertyChanged(String propertyName)
             {
                    if ((this.PropertyChanged != null))
                    {
                           this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                    }
             }
            
            
       }


Feito isso o mapeamento manual já esta pronto.

Mapeamento utilizando Assistente
Para fazer o mapeamento de forma automática é simples. Abra o arquivo Banco.dbml. 


Na guia “Server Explorer” selecione o banco de dados e arraste a tabela que deseja mapear para a dentro do arquivo Banco.dbml. 



Pronto o mapeamento já esta feito.

Utilização do Linq

Para trabalhar com o objeto mapeado é simples:
//Representa o Contexto mapeado no arquivo Banco.designer.cs
Banco bd = new Banco();

List<usuario> usuarios = bd.usuarios.ToList();
foreach (usuario usr in usuarios)
{
    Console.Write(usr.nome);
    Console.WriteLine();
}

Esse exemplo acima irá listar todos os usuários que estão no banco de dados.


Para inserir um novo registro é simples:
//Representa o Contexto mapeado no arquivo Banco.designer.cs
Banco bd = new Banco();
usuario u = new usuario();

u.id = Guid.NewGuid();
u.nome = "Celso";
u.email = "czequim@gmail.com";
bd.usuarios.InsertOnSubmit(u);
bd.SubmitChanges();


Se houver a necessidade de criar uma query, essa pode ser criada diretamente pelo C#. veja o exemplo:
List<usuario> query = (from resultado in bd.usuarios
                        where resultado.nome != ""
                        select resultado).ToList();

Esse arquivo é um exemplo básico de como trabalhar com LINQ. Em breve vou postar outros artigos mais completos. 


*Estou considerando que você tenha um conhecimento básico de banco da dados.

Um comentário: