ASP .NET - Salvando e recuperando Imagens no SQL Server usando o EF6
Neste artigo eu vou mostrar como podemos salvar e recuperar imagens em um banco de dados SQL Server usando o Entity Framework em uma aplicação ASP .NET Web Forms e a linguagem C#. |
O Entity Framework é atualmente a estratégia de acesso a dados recomendada pela Microsoft e oferece recursos para realizar praticamente todas as operações para consulta e manutenção de dados em um banco de dados relacional. Se você ainda usa a ADO .NET em seus projetos, ao migrar para o Entity Framework vai perceber o ganho de produtividade que ele oferece.
Ocorre que muitas tarefas as quais um programador ADO .NET tira de letra podem não ser assim tão simples de realizar com o Entity Framework, não pela complexidade, mas pela nova abordagem que deve ser dada ao problema.
Armazenar e recuperar imagens de um banco de dados é uma dessas tarefas. Como você já deve saber, podemos armazenar as imagens diretamente no banco de dados ou podemos optar por guardar somente a referência à imagem. Você deve considerar bem qual solução vai adotar pois cada uma tem suas vantagens e desvantagens.
Guardar a referência da imagem no banco de dados, é mais simples em termos de código e tem a vantagem de ocupar muito menos espaço do seu banco de dados. Você cria um campo no banco de dados onde guarda o caminho e o nome da imagem. Para exibir a imagem basta recuperar o caminho e nome da imagem exibindo-a em um controle PictureBox. A desvantagem, é que você terá que gerenciar a localização das imagens externamente a sua aplicação.
A maneira mais usada para armazenar dados binários é no sistema de arquivos de Windows, ou seja, armazenar os dados binários como um arquivo no disco local e a outra, a que irei mostrar neste artigo, é armazenar os dados binários diretamente no SQL Server.
Cada opção possui seus prós e seus contras, a seguir eu relaciono alguns motivos que podem justificar cada opção:
1 - Armazenar os dados binários como um arquivo no disco local é uma boa opção se :
O grande problema com esta solução que os dados estarão fora do banco de dados e podem perder a sincronia com os demais dados em operações de exclusão, atualização, inclusão e transferência de dados. Outro fator a considerar é que o backup deverá ser feito separado.
2 - Armazenar os dados binários diretamente no banco de dados SQL Server possui as seguinte vantagens:
Usando o tipo de dados varbinary do SQL Server podemos armazenar arquivos com até 2GB de tamanho.
Para estes
casos específicos o SQL Server fornece um tipo de dados especial
apropriados para um grande volume de dados e neste artigo eu vou mostrar
como podemos ler e gravar BLOBs - Binary Large Objects usando o SQL
Server e ADO .NET. Nota: BLOB é um acrônimo para binary large object , uma coleção de dados binários armazenados em um identidade única no SQL Server. Estes tipos de dados, Large Objects , podem ser classificados em CLOBs - Character Large Objects ou BLOBs - Binary Large Objects e o SQL Server possui um tipo diferente de dados para cada um destes objetos. Vejamos na tabela abaixo os tipos de dados que podemos usar neste caso:
|
Neste artigo eu procuro mostrar como salvar e recuperar imagens em um banco de dados SQL Server usando o Entity Framework em um projeto ASP .NET Web Forms.
Recursos usados:
Entity Framework 6
SQL Server 2012 Express
Definindo o modelo de dados
Vamos criar uma tabela chamada MinhasFotos no banco de dados Cadastro.mdf com a seguinte estrutura:
Observe que o campo Foto é do tipo varbinary(MAX) e irá armazenar as imagens que iremos salvar e recuperar do banco de dados.
Criando o projeto no Visual Studio 2013 Express for web
Abra o VS 2013 Express for web e clique em New Project;
Selecione a linguagem Visual C# e o template ASP .NET Web Application;
Informe o nome EF_SalvarImagem_BD e clique no botão OK;
A seguir selecione o template Empty e marque a opção Web Forms pois vamos criar um projeto vazio :
Vamos incluir uma nova página em nosso projeto. Para isso clique no menu PROJECT ->Add New Item e selecione o template Web -> Web Form e informe o nome Default.aspx e clique no botão Add;
Vamos criar um Entity Data Model no projeto Console. Selecione o projeto e Clique em PROJECT -> Add New Item;
Selecione a guia Data e o template ADO .NET Entity Data Model, informe o nome MinhasFotos e clique no botão Add;
No assistente selecione a opção EF Designer from database e clique no botão Next>;
Selecione a conexão com o banco de dados Cadastro.mdf (Se ele ainda não existir clique em New Connection e defina a conexão);
Aceite as configurações do assistente que salva a string de conexão no arquivo App.Config e cria o contexto CadastroEntities;
Clique no botão Next>;
Selecione a opção Entity Framework 6.x e clique no botão Next>;
A seguir selecione as tabelas do banco de dados e marque as opções conforme a figura abaixo clicando no botão Finish para concluir essa etapa:
Definindo o leiaute da página Default.aspx
Agora abra a página Default.aspx no modo Source e a partir da ToolBox inclua os seguintes controles:
FileUpolad : ID=fup1
Button : ID=btnIncluiImagem
TextBox : ID=txtDescricao, textMode=Multiline
Label : ID=lblStatus
Button : ID=btnExibirDados
GridView : ID=gdvFotos
Image : ID=imgFoto
Button : ID=btnExibirFoto
Disponha os controles conforme o leiaute da figura abaixo:
Agora vamos ao código definido no code-behind.
No evento Click do botão de comando Incluir Foto temos o código abaixo:
protected void btnIncluiImagem_Click(object sender, EventArgs e)
{
if (fup1.HasFile)
{
try
{
string filename = fup1.PostedFile.FileName;
int tamanho = fup1.PostedFile.ContentLength;
Stream arquivoStream = fup1.PostedFile.InputStream;
if (SalvarImagem(arquivoStream, filename, tamanho))
{
lblStatus.Text += "Imagem salva com sucesso no banco de dados";
}
else
{
lblStatus.Text += "FALHA ao salvar a imagem no Banco de dados";
}
}
catch (Exception ex)
{
lblStatus.Text = " Erro " + ex.Message;
}
}
}
|
Este código verifica se um arquivo de imagem foi selecionado e enviado usando o controle FileUpload (fup1), e obtém o nome do arquivo , seu tamanho e gera um Stream com a imagem selecionada.
A seguir usamos o método SalvarImagem() passando , o stream, o nome do arquivo e seu tamanho.
O código do método SalvarImagem() é visto a seguir:
private bool SalvarImagem(Stream arquivoStream, string filename, int tamanho)
{
bool ret = false;
try
{
byte[] documentBytes = new byte[arquivoStream.Length];
arquivoStream.Read(documentBytes, 0, documentBytes.Length);
MinhaFoto foto = new MinhaFoto()
{
Nome = filename,
Descricao = txtDescricao.Text,
Foto = documentBytes,
Tamanho = tamanho
};
using (CadastroEntities ctx = new CadastroEntities())
{
ctx.MinhasFotos.Add(foto);
ctx.SaveChanges();
ret = true;
}
}
catch (Exception ex)
{
lblStatus.Text = " Erro : " + ex.Message;
}
return ret;
}
|
O código acima cria um array de bytes a partir do stream do arquivo imagem , lê esses bytes e cria um instância da entidade MinhaFoto atribuindo os valores para a imagem definidos na página ASP .NET.
A seguir criamos uma instância do contexto (CadastroEntitites), adicionamos a entidade no contexto e persistimos as informações usando o método SaveChanges() do contexto.
Para exibir os dados gravados na tabela usando o evento Click do botão Exibir Dados com o código abaixo:
protected void btnExibirDados_Click(object sender, EventArgs e)
{
try
{
using (CadastroEntities ctx = new CadastroEntities())
{
gdvFotos.DataSource = from reg in ctx.MinhasFotos.ToList() select reg;
gdvFotos.DataBind();
}
}
catch(Exception ex)
{
lblStatus.Text = " Erro : " + ex.Message;
}
}
|
O código acima apenas cria uma instância do contexto e realiza uma consulta retornando as informações e atribuindo ao controle DataGridView (gdvFotos).
Para exibir uma foto selecionada no controle DataGridView usamos o código abaixo no evento Click do botão Exibir Foto :
protected void btnExibirFoto_Click(object sender, System.EventArgs e)
{
try
{
int codigo = Convert.ToInt32(gdvFotos.SelectedRow.Cells[1].Text);
byte[] bytes = (byte[])carregaImagem(codigo);
string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
imgFoto.ImageUrl = "data:image/png;base64," + base64String;
}
catch(Exception ex)
{
lblStatus.Text = " Erro " + ex.Message;
}
} |
Neste código obtemos o código da imagem selecionada no DataGridView e usando o método CarregaImagem() passamos esse código e retornamos um array de bytes que é convertido para String e exibido em um controle Image.
O código da rotina carregaImagem() é vista a seguir:
private byte[] carregaImagem(int id)
{
try
{
byte[] fileBytes = null;
using (CadastroEntities ctx = new CadastroEntities())
{
var dbInfo = ctx.MinhasFotos.FirstOrDefault(doc => doc.Id == id);
if (dbInfo != null)
{
fileBytes = dbInfo.Foto;
}
}
return fileBytes;
}
catch(Exception ex)
{
throw ex;
}
} |
Este código recupera a imagem armazenada realizando uma consulta LINQ com uma expressão lambda e retorna um array de bytes da imagem armazenada.
Executando o projeto, salvando algumas imagens e selecionando uma imagem para recuperar e exibir iremos obter o seguinte resultado:
Pegue o projeto completo aqui: EF_SalvarImage_BD.zip (sem as referências)
Porque os judeus pedem
sinal, e os gregos buscam sabedoria;
Mas nós pregamos a Cristo crucificado, que é escândalo para os judeus, e loucura
para os gregos.
Mas para os que são chamados, tanto judeus como gregos, lhes pregamos a Cristo,
poder de Deus, e sabedoria de Deus.
1 Coríntios 1:22-24
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Cadastro de Clientes com Entity Framework em - Macoratti.net