Arquivos da categoria: C#

Coleções em C# usando List

csharplogo

Nas linguagens de programação, o termo coleção é utilizado para definir estruturas capazes de agrupar objetos. Um simples vetor/array pode ser definido como uma coleção, neste caso, estática.

Em C# é facilmente possível criar coleções dinâmicas com o classe List<T>, disponível no namespace System.Collections.Generic.

Uma coleção gerada com List<T> fornece uma ótima opção, quando precisamos agrupar tipos de objetos (por exemplo, classes) de forma dinâmica e eficiente, e com métodos que possibilitam filtrar, ordenar e seus itens.

Vamos aos exemplos:

1 – Criando uma classe.

public class Pessoa
{
    int _id;

    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }
    string _nome;

    public string Nome
    {
        get { return _nome; }
        set { _nome = value; }
    }

    public Pessoa()
    {
        _id = 0;
        _nome = &quot;&quot;;
    }

    public Pessoa(int id, string nome)
    {
        this._id = id;
        this._nome = nome;
    }
}

2 – Criando e manipulando uma coleção da classe Pessoa (deve referenciar o namespace System.Collections.Generic).

using System.Collections.Generic;

//Criando uma lista que agrupará objetos da classe Pessoa.
List&lt;Pessoa&gt; pessoas = new List&lt;Pessoa&gt;();

//Adicionando objetos (tipo Pessoa) na lista.
pessoas.Add(new Pessoa(1, &quot;Andre&quot;));
pessoas.Add(new Pessoa(2, &quot;Brenda&quot;));

//Percorrendo a lista.
foreach (Pessoa p in pessoas)
{
   Console.WriteLine(p.Nome);
}

//Localizando uma pessoa.
Pessoa pessoa = pessoas.Find(delegate(Pessoa p1) { return p1.Id == 2; });

//Localizando várias pessoas que contenham no nome as letras &quot;nd&quot; (neste caso, o retorno é uma outra List&lt;Pessoas&gt; com as pessoas localizadas).
List&lt;Pessoa&gt; pessoasLocalizadas = pessoas.FindAll(delegate(Pessoa p1) { return p1.Nome.Contains(&quot;nd&quot;); });


//Removendo um item da lista pela sua posição.
pessoas.RemoveAt(0);

Mais detalhes em http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx.

Até…

Gerando estruturas JSON em C# e ASP.NET

json160Dando continuidade ao post Introdução ao JSON – Javascript Object Notation, mostro agora como construir em C# as estruturas dos exemplos utilizados no post anterior.

No C# podemos criar objetos de tipo anônimos (anonymous types) para definir a estrutura e dados, e depois realizar a serialização para o formato JSON.

Vamos aos exemplos:

1 – Criando um objeto.

public static string retornaObjetoJSON()
{
    //{“nome” : “Bill”, “idade” : 32, “salario”: 121232.67}

    var obj = new { nome = "Bill", idade = 32, salario = 121232.67};

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(obj);
    return strJson;
}

2 – Criando um array.

public static string retornaArrayJSON()
{
    //["Huguinho","Zezinho","Luizinho", 3]

    var objVet = new object[] { "Huguinho", "Zezinho", "Luizinho", 3 };

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(objVet);
    return strJson;
}

3 – Criando um array de objetos.

public static string retornaVetorDeObjetoJSON()
{
    /*
        [{ "nome" : "Huguinho", "idade" : 10 },
        { "nome" : "Zezinho", "idade" : 12 },
        { "nome" : "Luizinho", "idade" : 10 }]
    */

    var objVet = new object[] { new { nome = "Huguinho", idade = 10 },
                                new { nome = "Zezinho", idade = 12 },
                                new { nome = "Luizinho", idade = 10 }};

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(objVet);
    return strJson;
}

4 – Criando um objeto contendo um propriedade array de objetos.

public static string retornaObjetoComVetorJSON()
{
    /*
        {"tio" : "Pato Donald",
        "idade" : 40,
        "sobrinhos" :
                [{ "nome" : "Huguinho",     "idade" : 10 },
                { "nome" : "Zezinho", "idade" : 12 },
                { "nome" : "Luizinho", "idade" : 10 }]
        }
    */

    var obj = new {tio = "Pato Donald",
                    idade = 40,
                    sobrinhos = new object[] { new { nome = "Huguinho", idade = 10 },
                                                new { nome = "Zezinho", idade = 12 },
                                                new { nome = "Luizinho", idade = 10 }}
                    };

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(obj);
    return strJson;
}

A biblioteca System.Web.Script.Serialization é a responsável por realizar a serialização dos objetos anônimos.

Logo mais num outro post mostro como realizar chamadas assíncronas por Javascript ao JSON gerado no C# no servidor.

Até…

Filtrando as linhas do DataTable com LINQ

Imagine ter um DataTable carregado com os dados de uma consulta SQL, e a necessidade de melhorar o resultado (deixar mais específico). Normalmente faríamos uma nova consulta no banco de dados com uma instrução SQL com condições de retornar um resultado mais específico.

Uma facilidade interessante que descobri recentemente é filtrar linhas de um DataTable usando LINQ.

var filtro = (from DataRow dRow in dtPessoas.Rows
              where dRow[&quot;UF&quot;].Equals(&quot;SP&quot;)
              orderby dRow[&quot;nome&quot;].ToString()
              select dRow);

DataTable dtNovo = filtro.CopyToDataTable();

Neste exemplo, o DataTable (dtPessoas) mantém uma relação de pessoas, e por meio do LINQ é aplicado um filtro para obter todas as pessoas contidas no DataTable dtPessoas que moram no Estado SP.

Simples, não?

Upload de arquivos em ASP.NET

Pessoal.

Segue um exemplo rápido de como enviar arquivos ao servidor em ASP.NET usando o servercontrol UploadFile.

HTML:

&lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;
&lt;div&gt;
    &lt;asp:FileUpload ID=&quot;FileUpload1&quot; runat=&quot;server&quot; /&gt;
    &lt;asp:Button ID=&quot;btnEnviar&quot; runat=&quot;server&quot; Text=&quot;Enviar&quot;
        onclick=&quot;btnEnviar_Click&quot; /&gt;
    &lt;asp:Label ID=&quot;lMsg&quot; runat=&quot;server&quot;&gt;&lt;/asp:Label&gt;
&lt;/div&gt;
&lt;/form&gt;

C#:

        string caminhoArq = &quot;&quot;;
        try
        {
            if (FileUpload1.HasFile) //Verifica se um arquivo foi enviado
            {
                caminhoArq = Server.MapPath(&quot;~/arquivos/&quot;) + FileUpload1.FileName;
                FileUpload1.SaveAs(caminhoArq);
                lMsg.Text = &quot;Arquivo enviado com sucesso.&quot;;
            }
            else lMsg.Text = &quot;Selecione um arquivo.&quot;;
        }
        catch
        {
            lMsg.Text = &quot;Não foi possível enviar o arquivo.&quot;;
        }

O método MapPath da classe Server retorna o caminho físico do diretório “Arquivos”. É necessário pois o método SaveAs do FileUpload precisa de um caminho físico para entender onde salvar o arquivo.

É possível verificar o tamanho do arquivo enviado checando da propriedade ContentLength em FileUpload1.PostedFile. Seu valor é em bytes.


if (FileUpload1.PostedFile.ContentLength &gt; 10485760)
...

Também é possível checar o tipo do arquivo enviado. A propriedade ContentType em FileUpload1.PostedFile mantém o tipo MIME do arquivo.


if (FileUpload1.PostedFile.ContentType == &quot;application/pdf&quot;)
...

MIME Reference:

Fácil, simples, e funcional. Isso é ASP.NET.

O poder de usar Visões Parciais (partial views) com JQuery

Estou tentando aprender como criar página Web usando o Pattnern MVC 3 que acompanha o VisualStudio 2010. E hoje aprendi algo que me fascinou (pois no ASP.NET tradicional não é tão simples), invocar WebUserControls em chamadas AJAX. Vamos lá.

Uma Partial View é uma espécie de WebUserControl do MVC, ou seja, é possível criar pedaços de código a serem reaproveitados posteriormente em outras páginas.

Com o MVC é possível invocar via chamadas AJAX (neste caso com JQuery) Partial Views, ou seja, de forma simples posso via Ajax trazer o conteúdo da View que está no servidor.

A primeira coisa é criar a referência para biblioteca JQuery numa View normal ou MasterPage. E depois criar a Partial View e seu respectivo Action Controller.

Partial View OutroCurso.ascx:


&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;width: 608px&quot;&gt;
    &lt;tr&gt;
        &lt;td style=&quot;width: 288px&quot;&gt;
            Se sim, qual curso?&lt;br /&gt;
            &lt;%:Html.TextBox(&quot;txtQualCurso&quot;, &quot;&quot;, new { maxlength = &quot;10&quot;, style = &quot;width:264px&quot; })%&gt;
        &lt;/td&gt;
        &lt;td&gt;
            Em qual instituição?&lt;br /&gt;
            &lt;%:Html.TextBox(&quot;txtQualInstituicao&quot;, &quot;&quot;, new { maxlength = &quot;10&quot;, style = &quot;width:264px&quot; })%&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

Action Controller da Partial View OutroCurso.ascx:


public ActionResult OutroCurso()
{
    return PartialView();
}

E por fim, falta fazer a chamada AJAX para a Partial View acima dentro de uma View normal ou MasterPage.

A ideia do código abaixo é que o usuário ao selecionar o radiobutton SIM, apareçam outros campos a serem preenchidos (a Partial View). Observe que cada radionbutton em seu evento onclick chama a função JavaScript loadPartialViewOutroCurso, responsável por usar o método Load disponível na biblioteca JQuery para invocar a Partial View no servidor.

Possui outro curso superior?&lt;br /&gt;
&lt;%:Html.RadioButton(&quot;rblOutroCurso&quot;, &quot;N&quot;, false, new { onclick = &quot;loadPartialViewOutroCurso('N')&quot; })%&gt; Não
&lt;%:Html.RadioButton(&quot;rblOutroCurso&quot;, &quot;S&quot;, false, new { onclick = &quot;loadPartialViewOutroCurso('S')&quot; })%&gt; Sim
&lt;div id=&quot;divOutroCurso&quot;&gt;&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;

    function loadPartialViewOutroCurso(opcao) {

        if (opcao == 'S')
            $('#divOutroCurso').load('/Solicitacao/OutroCurso');
        else $('#divOutroCurso').html(&quot;&quot;);
    }

&lt;/script&gt;

A URL a “/Solicitacao/OutroCurso” é a rota para o Action (OutroCurso) do Controller (Solicitacao) que mantém a Partial View.

Bom né?

Abraço e até a minha próxima descoberta no mundo MVC.

Retornar dados no formato JSON usando ASP.NET

Olá pessoal.

Com o advento das chamadas assíncronas diretamente do cliente ao servidor via Javascript, muitas vezes é necessário retornar ao cliente dados estruturados,  que pode ser uma estrutura XML, uma simples string separada por um caractere especial, ou ainda no formato JSON.

Uma boa opção devido sua padronização e facilidade de manipulação é o formato JSON.

Serializar um objeto que é uma instância de uma classe para o formato JSON no C# é bem simples. O problema é quando queremos serializar dados que não representam um objeto de instancia de classe. Neste caso, a técnica mais comum é concatenar strings formando a estrutura desejada (já fiz muito isso), além de complicar uma futura manutenção, não é elegante.

No C# podemos criar objetos de tipo anônimos (anonymous types), definir sua estrutura e dados, e depois serializar para o formato  JSON enviando tudo  ao cliente.

Exemplo de criação de um vetor de tipo de anônimo e com dados:

var vetorAnonimo = new object[] { new { nome = "nome 1", id = 1 },
                                  new { nome = "nome 2", id = 2 }};

Com o objeto anônimo definido e carregado é possível fazer sua serialização para enviar ao cliente:

using System.Web.Script.Serialization;

JavaScriptSerializer js = new JavaScriptSerializer();
string strJson = js.Serialize(vetorAnonimo);

Pronto. É só devolver a variável strJson para a função de callback no Javascript/JQuery e manipular o retorno.

Veja como chega no cliente o vetor serializado, uma string estruturada no formato JSON. Lindo!!!

[{"nome":"nome 1","id":1},{"nome":"nome 2","id":2}]

Este post teve ajuda do @victorvhpg ninja do JQuery.

1º DojoPrudente

Olá pessoal.

Na noite de hoje (09/11) aconteceu o primeiro @dojoprudente. Foi um momento de troca de conhecimento, aprimoramento e muita diversão na sede da Activit. Imaginem só, um monte de programadores tentando resolver usando TDD um algoritmo para retornar os possíveis anagramas de uma palavra. Que vergonha, não conseguimos resolver (mas no primeiro pode hehehe).

Assim  que a equipe da tiprudente  publicar as fotos coloco o link aqui.

E até o próximo.

Mantendo o estado em páginas ASP.NET

Protocolo HTTP é um protocolo que não armazena informações entre suas requisições e resposta (stateless).

Não há implementações no protocolo HTTP que requisite que o browser identifique a si mesmo em cada requisição. Também não há nenhuma conexão estabelecida entre o browser e o servidor que persista entre uma página e a próxima, ou entre requisições para a mesma página, ou seja, o servidor envia os dados requisitados pelo cliente e não armazena nenhuma informação de estado. Se o cliente solicita a mesma informação, mesmo em um período de tempo pequeno, o servidor envia novamente sem nenhum critério.

Em qualquer desenvolvimento de sistemas Web pode ser aplicado técnicas de persistência de informações entre as requisições do usuário, como session e cookie. Além desta duas formas, no ASP.NET é possível usar um novo recurso chamado de VIEWSTATE.

Session

  • São informações armazenadas no servidor web para cada usuário de um determinado site;
  • Cada usuário possui suas próprias variáveis de sessão;
  • São destruídas ao fechar o navegador, ou no seu timeout, ou ainda quando solicitado pela aplicação;
  • As variáveis de sessões são globais dentro da sessão do usuário (qualquer página do servidor Web pode acessá-las).

Armazenando

Session.Add("INFORMACAO","Valor a ser armazenado");

Recuperando

if (Session["INFORMACAO"] != null) //testando a existência da session
    string x = Session["INFORMACAO"].ToString();

É importante testar a existência da session antes de tentar recuperar seu valor. Caso ela não exista, é disparado um erro ao tentar recuperar o valor.

Destruindo

Session.Remove("INFORMACAO");

Cookie

  • Trata-se de um pequeno arquivo de texto que é armazenado na máquina do usuário;
  • Cada site possui suas próprias cookies no computador do usuário;
  • Usado, por exemplo, em sites de comércio eletrônico, para exibir as  preferências e características do usuário;
  • São destruídas ao fechar o navegador, ou quando seu tempo de vida expira, ou ainda quando solicitado pela aplicação;
  • Pode identificar o usuário mesmo dias depois de seu acesso a página;
  • O grande problema dos cookies é que o usuário simplesmente pode desabilitar este recurso em seu navegador.

Armazenando

HttpCookie cookie = new HttpCookie("INFORMACAO");
cookie.Value = "Valor a ser armazenado";

//Envia a cookie ao cliente
Response.Cookies.Add(cookie);

É possível manipular o tempo de vida da cookie no cliente. No exemplo abaixo a cookie tem um tempo de vida de 7 dias.

cookie.Expires = DateTime.Now.AddDays(7);

//Envia a cookie ao cliente
Response.Cookies.Add(cookie);

Recuperando

if (Request.Cookies["INFORMACAO"] != null)
{
    string x = Request.Cookies["INFORMACAO"].Value;
}

É importante testar a existência da cookie antes de tentar recuperar seu valor. Caso ela não exista, é disparado um erro ao tentar recuperar o valor.

Destruindo
Para destruir a cookie é necessário definir um tempo de vida menor que o atual. Depois é só enviá-la ao cliente.

if (Request.Cookies["INFORMACAO"] != null)
{
    HttpCookie cookie = Request.Cookies["INFORMACAO"];
    cookie.Expires = DateTime.Now.AddDays(-1);

    //Envia a cookie ao cliente
    Response.Cookies.Add(cookie);
}

Para confirmar a operação criação/definição de valores e destruição da cookie é requerido seu envio ao browser cliente. Observe nos exemplos acima o uso do Response.Cookie.Add para enviá-la ao cliente.

ViewState

  • Mantêm automaticamente os valores de controles de servidor entre um postback e outro;
  • Internamente funciona como um campo oculto (hidden) um pouco mais sofisticado (__VIEWSTATE);
  • O ViewState é mantido somente na página, ao sair da página ele é perdido;
  • Ao rodar uma aplicação ASP.NET sem qualquer controle verá que é criado um campo oculto para o armazenamento do ViewState;
  • Os dados não são exibidos em texto plano, por questões de segurança;
  •  Pode-se ainda adicionar manualmente valores a um ViewState.

Armazenando

ViewState.Add("INFORMACAO","Valor a ser armazenado");

Recuperando

if (ViewState["INFORMACAO"] != null) //testando a existência do viewstate
    string x = ViewState["INFORMACAO"].ToString();

É importante testar a existência do viewstate antes de tentar recuperar seu valor. Caso ele não exista, é disparado um erro ao tentar recuperar o valor.

Destruindo

ViewState.Remove("INFORMACAO");

Até o próximo post.

ADO.NET: Manipulando banco de dados no .NET Framework

Este tópico vai tratar como acessar base de dados relacionais no .NET Framework.

Toda linguagem/plataforma de programação disponibiliza meios de acesso e manipulação de dados em banco de dados relacional, no .NET Framework não é diferente e trouxe consigo uma forma única e padronizada de acesso a dados, chamada ADO.NET, visando não só aplicações locais, mas também a Internet e os dispositivos móveis.

O ADO.NET é uma tecnologia baseada no clássico ADO (Active Data Objects) e faz parte de um conceito chamado UDA (Universal Data Access), o que permite que aplicativos se comuniquem com as mais diversas bases de dados usando a mesma metodologia, os mesmos objetos, a mesma abordagem. Ou seja, com o ADO.NET é possível acessar uma base dados SQL Server, Oracle, Firebird, Informix, PostGress, MySQL, e por aí vai…, sempre do mesmo jeito. Não temos que ficar apredendo uma nova forma acesso para cada tipo de SGBD.

Após definir o SGBD da aplicação é necessário procurar seu um provider .NET. A maioria dos fornecedores de SGBD disponibilizam em seus sites os providers. O provider para o SQL Server vem incluso na plataforma .NET. Se o SGBD escolhido não possui o provider, então é possível usar os providers genéricos ODBC ou OLEDB.

Os esses provider, tanto o específico (pode ser chamado de Nativo) como os genéricos são baseados num conjunto de classes, interfaces, tipos e enumerações, fornecedidos pelo .NET Framework o que permite aos fornecedores de bancos de dados implementarem as interfaces que permitirão acesso aos seus respectivos SGBDs, por isso é possível acessar diferentes SGBDs usando a mesma metodologia.

Este post vai utilizar o SGBD SQLServer nos exemplos com a base de dados Nortwind. Para usar outro SGBD, o provider deste deve ser referenciado ao projeto.

Estabelecendo uma conexão

Só é possível manipular uma base de dados após o estabelecimento da conexão. O ADO.NET oferece uma classe de interface para isso, a System.Data.IDbConnection. E para cada SGDB que possua seu provider específico existe a implementação dessa interface. Para o SQL Server a classe é SqlConnection, para o Oracle a OraConnection, para o MySQL a MySqlConnection, e por aí vai.

Para acontecer a conexão do ADO.NET com o banco de dados, é necessário informar o computador onde está o banco de dados, qual seu usuário e senha, através de uma string de conexão, que para cada SGBD é diferente. O site http://www.connectionstrings.com mantém uma ótima relação de tipos e strings de conexão.

Sabendo de tudo isso, aí vai o primeiro exemplo usando o banco de dados Northwind que acompanha o SQL Server Express.

//Importação do provider do SQLServer
using System.Data.SqlClient;

namespace appTeste
{
    class Program
    {
        static void Main(string[] args)
        {
            //Criação do objeto de conexão apontado para o banco de dados através da string de conexão.
            SqlConnection con = new SqlConnection(@&quot;Data Source=.SQLEXPRESS;Initial Catalog=Northwind;Persist Security Info=True;User ID=usuario; Password=senha&quot;);

            //Abertura do banco de dados
            con.Open();

            //Fechamento do banco de dados
            con.Close();
        }
    }
}

Para estabelecer a conexão não há segredo. É importar o provider, instanciar o objeto de conexão informando a string de conexão para a base e dados, abrir e fechar a conexão.

Uma boa prática de programação não demostrada aqui é sempre usar tratamento de erros ao acessar um banco de dados.

Definindo instruções SQL

A executação de instruções SQL é de responsabilidade da classe de interface System.Data.IDbCommand. Da mesma forma que acontece com a classe Connection, existe uma implementação para cada SGDB.

Um objeto do tipo Command deve estar ligado a uma conexão através de sua propriedade Connection e a instrução SQL a ser executada deve ser adicionada na propriedade CommandText no formato de string.

//Importação do provider do SQLServerusing System.Data.SqlClient;
using System.Data.SqlClient;

namespace appTeste
{
    class Program
    {
        static void Main(string[] args)
        {
            //Criação do objeto de conexão apontado para o banco de dados através da string de conexão.
            SqlConnection con = new SqlConnection(@&quot;Data Source=.SQLEXPRESS;Initial Catalog=northwind;Persist Security Info=True;User ID=usuario; Password=senha&quot;);

            //Abertura do banco de dados
            con.Open();

            //Criando o objeto command para execução de instruções SQL
            SqlCommand cmd = new SqlCommand();

            //Ligando o Command a conexão.
            cmd.Connection = con;

            //Informando a instrução SQL.
            cmd.CommandText = &quot;Insert into Region (RegionID, RegionDescription) Values (1000, 'Região...')&quot;;

            //Fechamento do banco de dados
            con.Close();
        }
    }
}

Um objeto do tipo Command possui a propriedade CommandType que define o tipo da execução. O valor padrão é Text, e indica que a string informada na propriedade CommandText é uma instrução Insert, Update, Delete ou Select.  Para executar Stored Procedures seu valor deve ser alterado para StoredProcedure.

cmd.CommandType = System.Data.CommandType.StoredProcedure;

Executando instruções SQL

Com a instrução SQL definida no objeto do tipo Command é possível executá-la. O objeto fornece basicamente três métodos de execução, o ExecuteNonQuery, ExecuteScalar e ExecuteReader.

1. ExecuteNonQuery: Utilizado quando se quer executar uma instrução que não retorna como resultado um conjunto de dados: Insert, Update, Delete e chamada a Stored Procedure. Seu retorno é um valor inteiro indicando o número de linhas afetadas na base de dados.

cmd.CommandText = &quot;Insert into Region (RegionID, RegionDescription) Values (1000, 'Região...')&quot;;

if (cmd.ExecuteNonQuery() &gt; 0)
    Console.WriteLine(&quot;Inserido&quot;);
else Console.WriteLine(&quot;Não inserido&quot;);
cmd.CommandText = &quot;Delete From Region Where RegionID = 1000&quot;;

if (cmd.ExecuteNonQuery() &gt; 0)
    Console.WriteLine(&quot;Excluído&quot;);
else Console.WriteLine(&quot;Não excluído&quot;);

2. ExecuteScalar: Retorna um único valor (uma coluna e uma linha). Tem seu desempenho otimizado para ser usado em funções SQL de agregação como count(*), sum(campo), avg(campo), max(campo), etc. Seu retorno é um objeto do tipo object, o que significa que pode representar qualquer tipo de dados.

cmd.CommandText = &quot;Select Count(*) From Region&quot;;

object conta = cmd.ExecuteScalar();

if (conta != null)
    Console.WriteLine(&quot;Quantidade de registros: &quot; + conta);
cmd.CommandText = &quot;Select Max(RegionID) From Region&quot;;

object maxRegionId = cmd.ExecuteScalar();

int proximoRegionId;

if (maxRegionId == null)
    proximoRegionId = 1;
else proximoRegionId = Convert.ToInt32(maxRegionId) + 1;

Console.WriteLine(&quot;Próximo registro: &quot; + proximoRegionId);

3. ExecuteReader: Utilizado para executar consultas (querys) que retornam um conjunto de dados. Este método tem como returno um objeto do tipo DataReader. Um objeto do tipo DataReader representa um cursor aberto somente para a frente e somente de leitura no banco de dados com os dados retornado de uma consulta. Após a leitura completa dos dados é necessário fechar o DataReader. Só é possível ter um DataReader aberto por conexão.

Um objeto do tipo DataReader somente dá acesso a uma linha do resultado por vez, e inicialmente não aponta para primeira linha. Através do método Read é possível acessar cada linha indivualmente, além disso retorna um valor booleano indicando se foi possível mover para a próxima linha. Para acessar a primeira linha do resultado é necessário usar o método Read movendo o cursor para ela.

cmd.CommandText = &quot;Select RegionID, RegionDescription From Region&quot;;

//Executando a consulta e recuperando o DataReader com o resultado
SqlDataReader dr = cmd.ExecuteReader();

//Para acessar a primeira linha é necessário mover o cursor para ela.
if (dr.Read())
    Console.WriteLine(dr[&quot;RegionDescription&quot;]);

//Liberando o cursor.
dr.Close();

Basta usar uma estrutura de repetição para percorrer todas as linhas do resultado.

while (dr.Read())
    Console.WriteLine(dr[&quot;RegionDescription&quot;]);

//Liberando o cursor.
dr.Close();

Importante destacar que não é possível acessar uma linha que já foi lida pelo DataReader, pois ele é um cursor que somente anda para frente.

Usando parâmetros nas instruções SQL

Uma boa prática é utilizar parâmetros e evitar a concatenação de strings para passar valores para as instruções SQL. Para indicar um parâmetro dentro da instrução, o SQL Server utiliza o símbolo “@”. Esta sintaxe pode variar de acordo com o banco de dados utilizado (o Oracle utiliza “:”).

Para atribuir valores aos parâmetros é necessário criar objetos de classes que implementam a interface System.Data.IDbDataParameter e adicioná-los ao objeto de comando (Command) na propriedade Parameters. No SQL Server a implementação é a classe SqlParameter.

cmd.CommandText = &quot;Insert into Region (RegionID, RegionDescription) Values (@RegionID, @RegionDescription)&quot;;

//Criando os parâmetros e atribuindo valores
SqlParameter regionID = cmd.CreateParameter();
regionID.ParameterName = &quot;@RegionID&quot;;
regionID.Value = &quot;1000&quot;;
//adicionando o parâmetro ao Command
cmd.Parameters.Add(regionID);

SqlParameter regionDescription = cmd.CreateParameter();
regionDescription.ParameterName = &quot;@RegionDescription&quot;;
regionDescription.Value = &quot;Região...&quot;;
//adicionando o parâmetro ao Command
cmd.Parameters.Add(regionDescription);

if (cmd.ExecuteNonQuery() &gt; 0)
    Console.WriteLine(&quot;Inserido&quot;);
else Console.WriteLine(&quot;Não inserido&quot;);

Também é possível utilizar métodos da propriedade Parameters do objeto Command para criar rapidamento os parâmetros e passar os valores.

cmd.CommandText = &quot;Insert into Region (RegionID, RegionDescription) Values (@RegionID, @RegionDescription)&quot;;

//Criando os parâmetros e atribuindo valores ao mesmo tempo
cmd.Parameters.AddWithValue(&quot;RegionID&quot;, 1000);
cmd.Parameters.AddWithValue(&quot;RegionDescription&quot;, &quot;Região....&quot;);

if (cmd.ExecuteNonQuery() &gt; 0)
    Console.WriteLine(&quot;Inserido&quot;);
else Console.WriteLine(&quot;Não inserido&quot;);

//Limpando a lista de parâmetros para aproveitar o mesmo Command
cmd.Parameters.Clear();

cmd.CommandText = &quot;Delete From Region Where RegionID = @RegionID&quot;;
cmd.Parameters.AddWithValue(&quot;RegionID&quot;, 1000);

if (cmd.ExecuteNonQuery() &gt; 0)
    Console.WriteLine(&quot;Excluído&quot;);
else Console.WriteLine(&quot;Não excluído&quot;);

Em algumas situações temos fornecer mais detalhes sobre os parâmetros além de seu nome e valor, por exemplo definir o tamanho da informação, o tipo de dados, ou mesmo informar que determinado parâmetro  é de saída (que retorna valores).

SqlParameter regionID = cmd.CreateParameter();
regionID.ParameterName = &quot;@RegionID&quot;;
regionID.Direction = System.Data.ParameterDirection.Output;
regionID.DbType = System.Data.DbType.String;
regionID.Size = 20;

Transações

Muitas vezes é necessário trabalhar com operações de insert, update ou delete que envolvem diversas tabelas, no estilo execute tudo ou nada. Um exemplo clássico é uma operação a venda de produtos, onde não pode haver uma venda de um produto sem um atualização em seu respectivo estoque.

No .NET transações são gerenciadas por objetos de classes derivados da interface System.Data.IDbTransaction, como a SqlTransacation para SQL Server.

//Abertura do banco de dados
con.Open();

//Criando o objeto de transação e iniciando
SqlTransaction transacao = con.BeginTransaction();

//Criando o objeto command e associando à transação
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;

try
{
    cmd.Transaction = transacao;

    //Executando a primeira atualização da base dados
    cmd.CommandText = &quot;Delete from Products Where CategoryID = 1&quot;;
    cmd.ExecuteNonQuery();

    //Executando a segunda atualização da base dados
    cmd.CommandText = &quot;Delete Categories Where CategoryID = 1&quot;;
    cmd.ExecuteNonQuery();

    //Confirmando as atualizações na base de dados, pois NÃO ocorreram erros.
    transacao.Commit();
}
catch
{
    //Desfazendo as atualizações na base de dados, pois ocorreram erros.
    transacao.Rollback();
}

con.Close();

É isso pessoal. Espero que ajude. 😉

Removedor de injeção de SQL

Olá pessoal.

Segue um simples código para remover uma possível injeção de SQL.

O código simplesmente substitui o que é considerado perigo por vazio. O legal é o uso do método Replace da classe Regex (expressões regulares) que ignora o case não momento da substutição dos valores.

using System.Text.RegularExpressions;


public static string RemoveInjecao(string texto)
{
	string[] caracteresInvalidos1 = { &quot;select &quot;, &quot;drop &quot;, &quot;--&quot;, &quot;insert &quot;, &quot;delete &quot;, &quot;xp_&quot;, &quot;'&quot;, &quot;%&quot;, &quot;update &quot;, &quot;group by &quot;, &quot;having &quot;, @&quot;sum(&quot;, @&quot;count(&quot;, &quot;alter table&quot;, &quot; – &quot;, &quot;–&quot;, &quot; –&quot;, &quot;– &quot;, &quot;varchar&quot;, &quot;declare&quot;, @&quot;cast(&quot;, @&quot;exec(&quot; };

	for (int i = 1; i &lt; caracteresInvalidos1.Length; i++)
	{
		//replace que ignora o case (maiúsculo/minúsculo)
		texto = Regex.Replace(texto, caracteresInvalidos1[i], &quot;&quot;, RegexOptions.IgnoreCase); 
	}	
	return texto.Trim();
}

Fica a dica!