Mostrando postagens com marcador orientação. Mostrar todas as postagens
Mostrando postagens com marcador orientação. Mostrar todas as postagens

segunda-feira, 27 de maio de 2013

LINQ to Entities

Utilizar LINQ to SQL é fácil,  mas só funciona com banco de dados MS-SQL.  

E se minha necessidade for utilizar o MySQL como banco de dados? Nesse caso teremos que utilizar o LINQ to Entities. O conceito é o mesmo e funciona para qualquer banco de dados.
Nesse caso eu vou utilizar o MySQL 5. 5.0.45.


Criei uma tabela com a seguinte estrutura:

Onde a coluna id  é por padrão incrementada 1 a 1.

Já no Visual Studio, precisamos adicionar uma conexão apontando para o MySQL.
Clique na guia Server Explorer e clique em adicionar conexão.  A janela a seguir irá aparecer:

Escolha MySQL e clique em ok.


Preencha os campos conforme seu banco de dados. No meu caso o nome do banco de dados é Projeto e esta localizada no Localhost. Vou usar o usuário root para acessar.

Após criar a conexão, é necessário adicionar o item ADO.NET Entity Data Model, como abaixo . Vou nomear o arquivo como Banco.edmx e clicar em Add. 



A janela a seguir será apresentada, escolha a opção “Generate from database”  e clique em Next.
Escolha a conexão para o banco de dados. E clique em Next.
Será apresentada a janela a seguir, nessa janela podemos escolher as entidades que vamos utilizar. No meu caso, somente a entidade usuário. Clique em Finish


Pronto, o mapeamento já foi feito e podemos trabalhar com a entidade criada.
Para inserir um registro faremos da seguinte maneira:
Banco bd = new Banco();//Representa o contexto do banco de dados

usuario u = new usuario();
u.nome = "Celso Zequim";
u.email = "czequim@gmail.com";
bd.AddTousuario(u);
bd.SaveChanges();

Ao pressionar F5, podemos ver que o registro foi inserido no Banco de dados:

Para ler essa informação e exibir no console é simples:

var usuarios = from ur in bd.usuario orderby ur.nome select ur;
foreach (usuario usr in usuarios)
{
       Console.Write(usr.nome);
       Console.WriteLine();               
}
           
O resultado é o seguinte:

Simples... e funciona para qualquer banco de dados, como: MySQL, Oracle, Postgres, Firebird... etc. 


:D


segunda-feira, 15 de abril de 2013

Upload e Download de arquivo com LINQ


Fazer um upload de um arquivo qualquer para o banco de dados através do LINQ é muito fácil.


Criei em meu banco de dados uma tabela chamada documento, com os seguintes campos:
Tipo de dados:
Id – Uniqueidentifier
Nome – Varchar(max)
Arquivo – Image

Adicionei ao projeto um arquivo do tipo LINQ to SQL  com o nome de Banco.dbml  e adicionei a tabela documento.

Feito isso, precisamos criar a página que irá enviar o arquivo. No meu caso é a Default.aspx. veja como ficou o código:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="ExemploWeb._default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:FileUpload ID="UpArquivo" runat="server" />

        <br />

        <asp:Button ID="BtnEnviar" Text="Enviar" runat="server"
            onclick="BtnEnviar_Click"  />
    </div>
    </form>
</body>
</html>


O controle “asp:FileUpload” é necessário para fazer o upload e o controle do tipo Button que irá realizar toda mágica.  Repare que eu adicionei um evento chamado onClick e apontei para a função “BtnEnviar_Click”.  Essa função deverá ser criada no arquivo Default.aspx.cs. Veja abaixo:

       protected void BtnEnviar_Click(object sender, EventArgs e)
        {
            if (UpArquivo.HasFile && UpArquivo.PostedFile.ContentLength > 0)
            {

                byte[] _arquivo = UpArquivo.FileBytes;

                BancoDataContext bd = new BancoDataContext();
                documento doc = new documento();
                doc.id = Guid.NewGuid();
                doc.nome = UpArquivo.FileName;
                doc.arquivo = _arquivo;
                bd.documentos.InsertOnSubmit(doc);
                bd.SubmitChanges();

            }
        }

No exemplo acima eu armazenei o  arquivo, em formato de bytes, na variável _arquivo. Após armazenar o arquivo  foi criado um Contexto do meu banco de dados, dei o nome de bd. Esse contexto vem do LINQ e é responsável pela ligação do C# com o SQL.

Criei uma nova instancia do objeto documento e atribuir os valores, id, nome e arquivo.
O método InsertOnSubmit é responsável por guardar o objeto em cache até executar o submit, que é o método SubmitChanges, Até esse momento o registro ainda não existe no banco de dados.

Veja como ficou:
Clicando no botão “Escolher arquivo” a seguinte janela será exibida:

Vou escolher esse arquivo PDF e clicar em open.


Feito isso é só clicar em enviar.  O resultado já pode ser visto no banco de dados. 


Para realizar o Download do arquivo basta colocar esse trecho de código no evento do botão download, que pode ser criado exatamente como o botão enviar.
protected void BtnDownload_Click(object sender, EventArgs e)
        {
            BancoDataContext bd = new BancoDataContext();
            var arquivos = from c in bd.documentos select c;
            foreach (documento arquivo in arquivos)
            {
                Response.AddHeader("Content-Disposition", "attachment; filename=" + arquivo.nome);
                Response.ContentType = "application/x-zip-compressed";

                if (arquivo.arquivo != null)
                    Response.BinaryWrite(arquivo.arquivo.ToArray());
            }

        }







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.

Objetos


Quando falo de objetos não vejo uma definição mais simples essa:
Um objeto é uma instância (ou seja, um exemplar) de uma classe.

Veja no exemplo abaixo a criação de uma classe simples:                              
class Usuario
{
public Usuario() { }
public Usuario(string nome, string email)
{
this.nome = nome;
this.email = email;
}
private string _nome;
private string _email;
public string nome { get { return _nome; } set { _nome = value; } }
public string email { get { return _email; } set { _email = value; } }
public string Concatenar()
{
return nome + email;
}


}

Uma classe define os atributos e comportamentos comuns compartilhados por um tipo de objeto.

No exemplo acima foi criada uma Classe chamada de Usuario onde:
  • _nome = Atributo
  • _email = Atributo
  • nome = Propriedade
  • email =Propriedade
  • Concatenar() = Método
  • Usuario() = Construtor

A utilização do objeto ficaria da seguinte forma:
Usuario usuario = new Usuario();
usuario.nome = "Celso";
usuario.email = "czequim@gmail.com";

No exemplo acima foi declarado uma instancia da classe Usuario com o nome usuario e definimos valores para as duas propriedades.

Uma outra forma de criar o objeto e definir os valores é da seguinte forma:

Usuario usuario = new Usuario("Celso", "czequim@gmail.com");           

Isso só é possível pois criamos um construtor que espera esses valores:
public Usuario(string nome, string email)
{
this.nome = nome;
this.email = email;
}


Para chamar o método Concatenar é muito simples, veja o exemplo:
Console.Write(usuario.Concatenar());           

Esse método retornará o resultado de nome+email