NUNCA MAIS PASSE RAIVA POR NÃO CONSEGUIR RESOLVER UM PROBLEMA COM O EXCEL - GARANTIDO!
UNIVERSIDADE DO VBA - Domine o VBA no Excel Criando Sistemas Completos - Passo a Passo - CLIQUE AQUI
Bom, meu objetivo é mostrar como criar de uma nova forma cache de acesso a dados com pool de conexões. Com o uso da internet e as facilidades que a mesma atribui a todos que a utilizam, surgiu outra preocupação com softwares e sites dinâmicos, acesso a banco de dados, número de pessoas que acessam sistemas pela internet. A rapidez das informações mostradas ao cliente conta muito para que haja confiança e credibilidade pela parte do usuário.
Imagine uma pessoa acessando ao site que automaticamente busca a informação do banco de dados, não importa qual banco. Um cliente acessando o banco de dados é bem tranqüilo, agora imagine 10.000 clientes ao mesmo tempo acessando o mesmo site de notícias ou de venda de produtos. Se o software desenvolvido não foi preparado para essa quantidade de pessoas acessando ao mesmo momento, pode ocorrer um risco de travar ou elevar o nível de processamento e memória do servidor, ou seja, caso não tratado de uma forma correta, pool de conexões ou aproveitamento de conexão já criada, pode demorar por demais mostrar ao usuário ou cliente a notícia ou produto. Quem perde é você dono do site ou empreendimento de vendas, nos dias de hoje os usuários já não têm muita paciência para esperar muito tempo, isso é um erro muito grave junto aos jovens, crianças e adultos; não saber esperar 30 segundos, 10 segundos, o que seja.
Referências necessárias:
- Framework 2.0;
- Visual Studio .NET 2005;
- Sql Express 2005;
- Linguagem C#.NET;
- Imagine que um projeto do tipo WEB já esteja criado.
A criação de cache e pool de conexão para a versão 2005 da IDE Visual Studio .NET está mais robusta e eficaz do que a versão anterior. O arquivo web.config já está preparado para a funcionalidade. O primeiro de tudo é criar e configurar o caching. Referência 1.1.
Arquivo WEB.CONFIG
<connectionStrings>
<add name="SiteDB" connectionString="Data Source=.\SQLEXPRESS;
Integrated Security=True; User Instance=True;
AttachDBFilename=|DataDirectory|\AspNetDB.mdf;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="10000">
<databases>
<add name="siteDB" connectionStringName="SiteDB" pollTime="2000"/>
</databases>
</sqlCacheDependency>
</caching>
</system.web>
Referência: 1.1
Explicação:
A primeira tag <connectionStrings> é a nova forma utilizada para conexão com banco de dados sql express 2005. O nome do banco de dados criado é ASPNETDB.mdf. O nome “SiteDB” é para referenciá-lo dentro do código C#.NET a string de conexão.
<caching>
<sqlCacheDependency enabled="true" pollTime="10000">
<databases>
<add name="siteDB" connectionStringName="SiteDB" pollTime="2000"/>
</databases>
</sqlCacheDependency>
</caching>
Referência: 1.2
A tag está localizada dentro da <system.web> logo após do fecho </connectionStrings>. Habilito o sqlCacheDependecy com o pollTime igual a 10000. Abri uma outra tag chamada <databases> onde defino qual a conexão do banco de dados utilizar com um pollTime específico a ele.
<add name="siteDB" connectionStringName="SiteDB" pollTime="2000"/>
Referência: 1.3
Na referência 1.3, adicionei um nome “siteDB” minúsculo onde indico a connectionStringName referenciada na string de conexão anteriormente, ou seja, a que está dentro da <connectionStrings>. O atributo connectionStringName possui o mesmo nome da connectionString, isso significa que foi referenciado qual o pool escolhido para determinado banco de dados. Essa nova funcionalidade é legal porque posso referencia ou colocar quantos bancos de dados quiser para dentro da aplicação. Grave bem o atributo name adicionado de forma minúscula, usarei em breve dentro do código para fazer o caching.
Depois de configurado no web.config vou direto para o banco de dados definir tabela e campos. Referência 1.4.
Referência: 1.4
No banco de dados defini apenas dois campos como na figura de referência 1.4. Não esqueça de colocar o campo ID como auto-incremento. O campo CustomerName é do tipo nvarchar e do tamanho de 100 caracteres, ou seja, serve apenas para colocar o nome.
Este banco foi criado utilizando a IDE Visual Studio.NET 2005 pela aba SOLUTION EXPLORER. (Referência 1.5)
Referência: 1.5
Depois de criado o banco de dados, populei alguns dados.
Codificando código na classe
Cliquei com o botão direito do mouse em cima do projeto e adicionei um novo item cujo o “template” é o “Class”. Coloquei o nome de CustomerDetails.cs que ficou dentro da pasta APP_CODE. Dentro da classe adicionei apenas Get e Set dos campos criados no banco de dados, ou seja, mapeamento do banco de dados. Referência 1.6
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/// <summary>
/// Summary description for CustomerDetails
/// </summary>
public class CustomerDetails
{
public CustomerDetails()
{
//
// TODO: Add constructor logic here
//
}
private int _id;
private string _customerName;
public string CustomerName
{
get { return _customerName; }
set { _customerName = value; }
}
public int Id
{
get { return _id; }
set { _id = value; }
}
}
Referência: 1.6
Note que declarei as variáveis, uma do tipo int e outra do tipo string. Para gerar o Get e Set automático, utilize o atalho CRTL + R e CRTL + E posicionado o mouse em cima da variável. Caso contrário utilize o menu refactory / encapsulate field...
Referência: 1.7
A referência 1.7 mostra o local correto onde ficou a classe criada apenas com o Get e Set dos campos. Depois de montado e configurado corretamente, criei a página “Default.aspx” para mostrar os resultados.
Aviso antes que não utilizarei o padrão MVC porque iria aumentar muito este artigo falando apenas de MVC, cujo não é o nosso objetivo, mas sim mostrar como funciona o novo sistema utilizando cache e sqldependency.
Dentro da página “Default.aspx”, adicionei o componente GridView com dois campos BoundField. Estes dois campos foram declarados com o mesmo nome da classe “CustomerDetails.cs”. Referência 1.8
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_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>CACHE</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="id" />
<asp:BoundField DataField="customerName" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
Referência: 1.8
Dentro da classe “Default.aspx.cs” é onde está o segredo para o cache. No Page_Load preencho o componente GridView chamando um método. Referência 1.9.
protected void Page_Load(object sender, EventArgs e)
{
this.GridView1.DataSource = GetDados();
this.GridView1.DataBind();
}
Referência: 1.9
GetDados() é um método que retorna um List<CustomerDetails> utilizando genérics. Antes de criar o método, importe as seguintes classes. Referência 1.10.
//importes
using System.Web.Caching;
using System.Data.SqlClient;
using System.Collections.Generic;
Referência: 1.10
O método GetDados não recebe parâmetros porém retorna uma lista de dados. Utilizarei SqlDataReader para buscar os dados e preencher a lista.
private List<CustomerDetails> GetDados()
{
List<CustomerDetails> customers = null;
if (Cache["Customers"] != null)
{
customers = (List<CustomerDetails>)Cache["Customers"];
}
else
{
using (SqlConnection cn = new SqlConnection(System.Configuration.ConfigurationManager.
ConnectionStrings["SiteDB"].ConnectionString))
{
try
{
SqlCommand cmd = new SqlCommand("Select id, CustomerName from Customers", cn);
cn.Open();
List<CustomerDetails> list = new List<CustomerDetails>();
customers = FillDados(cmd, list);
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(System.
Configuration.ConfigurationManager.ConnectionStrings["SiteDB"].
ConnectionString);
SqlCacheDependencyAdmin.EnableTableForNotifications(System.Configuration.
ConfigurationManager.ConnectionStrings["SiteDB"].ConnectionString,
"Customers");
SqlCacheDependency dep = new SqlCacheDependency("siteDB", "Customers");
Cache.Insert("Customers", customers, dep);
}
catch (DatabaseNotEnabledForNotificationException ex)
{
throw ex;
}
}
}
return customers;
}
Referência: 1.11
Explicação:
Antes de tudo, a análise da assinatura do método é muito importante para o resto do entendimento. Referência 1.12.
private List<CustomerDetails> GetDados()
Referência: 1.12
É do tipo privado, não recebe dados e retorna um List<CustomerDetails> cujo é a classe criada anteriormente.
List<CustomerDetails> customers = null;
if (Cache["Customers"] != null)
{
customers = (List<CustomerDetails>)Cache["Customers"];
}
Referência: 1.13
O próximo passo foi declarar uma lista chamada customers igualando ao valor null. Em seguida adicionei uma condição perguntando se o “Cache[“Customers”]” é diferente de null, caso for, a lista “customers” declarada acima receber um cache de dados do Cache[“Customers”].
Caso não tiver preenchido será necessário ir ao banco de dados utilizando a string de conexão do web.config, fazer um select, buscar os dados e preencher a lista de dados. Referência 1.14
else
{
using (SqlConnection cn = new
SqlConnection(System.Configuration.ConfigurationManager.
ConnectionStrings["SiteDB"].ConnectionString))
{
try
{
SqlCommand cmd = new SqlCommand("Select id, CustomerName from Customers", cn);
cn.Open();
List<CustomerDetails> list = new List<CustomerDetails>();
customers = FillDados(cmd, list);
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications
(System.Configuration.ConfigurationManager.ConnectionStrings["SiteDB"].
ConnectionString);
SqlCacheDependencyAdmin.EnableTableForNotifications(System.
Configuration.ConfigurationManager.ConnectionStrings["SiteDB"].
ConnectionString, "Customers");
SqlCacheDependency dep = new SqlCacheDependency("siteDB", "Customers");
Cache.Insert("Customers", customers, dep);
}
catch (DatabaseNotEnabledForNotificationException ex)
{
throw ex;
}
}
}
Referência: 1.14
No else, a primeira linha é buscar a conection string. Referência 1.15
using (SqlConnection cn = new
SqlConnection(System.Configuration.ConfigurationManager.
ConnectionStrings["SiteDB"].ConnectionString))
Referência: 1.15
Lembre-se que dentro do web.config existe o nome [SiteDB] cujo é a conectionstring adicionada logo no começo deste artigo. Passando para as próximas linhas do código, adicionei try e catch onde faz select no banco de dados, executa datareader, preenche os dados e faz o cache. Referência 1.16
try
{
SqlCommand cmd = new SqlCommand("Select id, CustomerName from Customers", cn);
cn.Open();
List<CustomerDetails> list = new List<CustomerDetails>();
customers = FillDados(cmd, list);
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(System.
Configuration.ConfigurationManager.ConnectionStrings["SiteDB"].
ConnectionString);
SqlCacheDependencyAdmin.EnableTableForNotifications(System.
Configuration.ConfigurationManager.ConnectionStrings["SiteDB"].
ConnectionString, "Customers");
SqlCacheDependency dep = new SqlCacheDependency("siteDB", "Customers");
Cache.Insert("Customers", customers, dep);
}
catch (DatabaseNotEnabledForNotificationException ex)
{
throw ex;
}
Referência: 1.16
Explicação:
Logo após o try adicionei um SqlCommand com um select dos campos, abri o banco de dados com o comando Open() e criei uma nova variável list do tipo List<CustomerDetails>. Referência 1.17.
SqlCommand cmd = new SqlCommand("Select id, CustomerName from Customers", cn);
cn.Open();
List<CustomerDetails> list = new List<CustomerDetails>();
Referência: 1.17
Dentro deste método, acabei acessando outro para buscar e executar o SqlDataReader adicionando na lista todo o resultado. Este método chama “FillDados”.
customers = FillDados(cmd, list);
Referência: 1.18
Note que este novo método recebe como entrada SqlCommand e a lista de dados. A lista customers recebe o resultado do método. Antes de terminar o método “GetDados”, mostrarei o método FillDados. Referência 1.19.
private List<CustomerDetails> FillDados(SqlCommand cmd, List<CustomerDetails> list)
{
using (SqlDataReader dataReader = cmd.ExecuteReader())
{
while (dataReader.Read())
{
CustomerDetails coll = new CustomerDetails();
coll.Id = (int)dataReader["id"];
coll.CustomerName=(String)dataReader["CustomerName"];
list.Add(coll);
}
return list;
}
}
Referência: 1.19
Explicação:
Adicionei a variável dataReader executando o comando cmd.ExecuteReader(). Enquanto estiver dados crio uma variável “coll” do tipo CustomerDetails e atribuo os campos Id igual ao resultado do Reader[“id”]. Da mesma forma faço com o CustomerName; adiciono o dataReader[“CustomerName”] e ao final pego a lista criada e adiciono com o Add(coll) passando a variável coll.
Ao final preciso retornar uma lista, esta lista deve ser do tipo List<CustomerDetails> cujo tenho o list. Referência 1.20.
return list;
Referência: 1.20
Após retornar a list do método “FillDados” preciso habilitar o cache pelo sqlCacheDependencyAdmin cujo deixo ativo o banco de dados para cache. Preciso habilitar a tabela do banco de dados utilizando o EnableTableForNotifications. No final insiro o cache utilizando o método Cache.Insert. Referência 1.21
customers = FillDados(cmd, list);
//habilita o cache para o banco de dados para o uso do cache
System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(System.
Configuration.ConfigurationManager.ConnectionStrings["SiteDB"].
ConnectionString);
//habilita a tabela do banco de dados para o uso do cache
SqlCacheDependencyAdmin.EnableTableForNotifications(System.
Configuration.ConfigurationManager.ConnectionStrings["SiteDB"].
ConnectionString, "Customers");
SqlCacheDependency dep = new SqlCacheDependency("siteDB","Customers");
//inserir o cache
Cache.Insert("Customers", customers, dep);
Referência: 1.21
Explicação:
Note que a linha que habilita o SqlCacheDependencyAdmin serve para autorizar que determinado banco de dados possa utilizar cache. Tenho que passar como parâmetro a conectionString dentro do web.config.
SqlCacheDependency dep = new SqlCacheDependency("siteDB","Customers");
Referência: 1.22
Na referência 1.22 é onde indico o nome da tag informada dentro do web.config e o nome da tabela cujo desejo fazer o cache. Logo após basta utilizar o cache.Insert passando a variável criada do tipo SqlCacheDependecy.
Cache.Insert("Customers", customers, dep);
Referência: 1.23
Com este método, coloco a chave como parâmetro, a lista de dados e a variável cache. Vejamos o funcionamento do sistema.
Cliquei F5 para iniciar o sistema.
Referência: 1.24
Pela primeira vez, o cache ainda não foi feito, portanto o mesmo utiliza o select com todo o procedimento. Coloquei um breakpoint junto ao método PAGE_LOAD. Referência 1.25.
Referência: 1.25
Apertei F5 no browser e notei que não passou nem mesmo pelo breakpoint que coloquei, ou seja, foi criado um cache cujo nem mesmo precisou acessar o método para retornar os dados.
Bom, espero que tenham gostado. Fico por aqui e qualquer problema favor entrar em contato pelo e-mail: mauricio@aspneti.com ou mauricio@ascompras.com.
Mauricio Junior
Contato: Telefone: (51) 3717-3796 | E-mail: webmaster@juliobattisti.com.br | Whatsapp: (51) 99627-3434
Júlio Battisti Livros e Cursos Ltda | CNPJ: 08.916.484/0001-25 | Rua Vereador Ivo Cláudio Weigel, 537 - Universitário, Santa Cruz do Sul/RS, CEP: 96816-208
Todos os direitos reservados, Júlio Battisti 2001-2025 ®
LIVRO: MACROS E PROGRAMAÇÃO VBA NO EXCEL 2016 - CURSO COMPLETO E PRÁTICO
DOMINE A PROGRAMAÇÃO VBA NO EXCEL - 878 PÁGINAS - CLIQUE AQUI