jueves, 18 de agosto de 2011

Almacenando Imagenes en nuestra Base de Datos desde SQL Server 2008

En este post aprenderemos como almacenar datos en nuestra base de datos y luego poderlos visualizarlos en un grid para ello iniciaremos creando una tabla a la cual llamaremos Producto.
En el campo donde almacenaremos la imagen el tipo de dato sera image

Luego de habe creado nuestra tabla crearemos un procedimiento almacenado para registrar y otro para consultar los datos.

Ahora abriremos el visual studio y crearemos un proyecto per en este caso agregaremos una solucion en blanco ya que lo realizaremos por capas.

Despues que tenemos la solucion en blanco procedemos a agregar las diferentes capas asi como lo muestra las imágenes siguientes.
Agregaremos una Class Library ya que en este crearemos la capa de Entity layer asi como lo muestra la imagen siguiente.

Luego que hemos agregado Eliminamos la clase que aparece por default

El mismo paso hacemos para agregar la capa BL y DL. Y por ultimo agregamos la capa para la interfaz de usuario en este caso en WPF
En la Entity Layer agregaremos la referencia System.Runtime.Serialization   
Despues de lo anterior creamos la clase Productos_CS que llevara los siguientes campos.
Ya que tenemos la Clase pasaremos a la capa DL en el cual comenzaremos agregando la referencia Ejemplo.Productos.EL ya que nos serviara a la hora invocar a la clase Producto.
Ahora hacemos la coneccion con la base de datos asi como lo muestra la siguiente imagen
Despues que se ha hecho la coneccion a la base de datos comenzamos a crear la clase DBCommon este nos servira para hacer las conexiones correspondientes.
using System.Data;
using System.Data.SqlClient;
namespace Ejemplo.Productos.DL
{
    public class DBCommon
    {
        public enum TipoBaseDeDatos
        {
            SqlServer,
            Oracle,
            DB2
        };
        public const string ConnectionString = @"Data Source=JAIRO-PC\SQLEXPRESS;Initial Catalog=BaseProductos;Integrated Security=True";
        public static IDbConnection ObtenerConexion(TipoBaseDeDatos pTipoBaseDeDatos)
        {
            IDbConnection _connection;

            if (pTipoBaseDeDatos == TipoBaseDeDatos.SqlServer)
            {
                _connection = new SqlConnection(ConnectionString);
                _connection.Open();

                return _connection;
            }
            return null;
        }
        public static IDataReader EjecutarDataReader(IDbConnection pConnection, string psqlString, TipoBaseDeDatos pTipoBaseDeDatos)
        {
            if (pTipoBaseDeDatos == TipoBaseDeDatos.SqlServer)
            {
                SqlCommand _command = new SqlCommand(psqlString, pConnection as SqlConnection);

                return _command.ExecuteReader(CommandBehavior.CloseConnection);
            }
            return null;
        }
    }

ahora en la clase ProductoDAL realizaremos el metodo GuardarProducto como lo muestra la siguiente imagen.

Este sera el metodo para Mostrar la image.


Luego que ya tenemos en DL nuestros metodos comenzaremos en la BL a agregar la referencia DL y EL.
Recordamos que debemos de colocar los namespace, nuestros metodos quedaria asi:
Ya que tenemos defenidos nuestros metodos comenzaremos a hacer el diseño en nuestro WPF para comenzar agregaremos la referencias BL y EL
El diseño de la pantalla en WPF quedaria de la siguient manera.
Ahora agregaremos los namespaces a utillizar
using System.IO;
using System.ComponentModel;
using Microsoft.Win32;
using Ejemplo.Productos.EL;
using Ejemplo.Productos.BL;


Ahora declaramos una variable de tipo byte ya que convetiremos nuestra imagen en byte para ser almacenada.

namespace Ejemplo.Productos.UI.WPF
{
    /// <summary>
    /// Interaction logic for Producto.xaml
    /// </summary>
    public partial class Producto : Window
    {
        byte[] imagenbyte;
        BitmapDecoder bitdecoder;
        Int64 pId;
        ProductosBL _ProductoBL = new ProductosBL();
        public Producto()
        {
            InitializeComponent();
        }

En el Boton Guardar ira el siguiente codigo:

        private void btnGuardar_Click(object sender, RoutedEventArgs e)
        {
            Productos_CS _Producto = new Productos_CS()
            {
                Nombre = txtNombre.Text,
                Precio = Convert.ToDecimal(txtPrecio.Text),
                Existencia = Convert.ToInt16(txtExistencias.Text),
                Imagen = imagenbyte,
                Id_Producto = (-1),

            };
            _ProductoBL.GuardarProducto(_Producto);
            MessageBox.Show("Registro Guardado", "Productos", MessageBoxButton.OK);
            Close();
        }


Para cargar nuestra imagen en el image realizaremos el siguiente codigo en boton:

        private void btnFoto_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Imagenes jpg(*.jpg)|*.jpg|All Files (*.*)|*.*";

            if (ofd.ShowDialog() == true)
            {
                using (Stream stream = ofd.OpenFile())
                {
                    bitdecoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                    image1.Source = bitdecoder.Frames[0];
                    txtImagen.Text = ofd.FileName;


                }
            }
            else
            {
                image1.Source = null;
            }

            System.IO.FileStream fs;
            fs = new System.IO.FileStream(txtImagen.Text, System.IO.FileMode.Open);
            imagenbyte = new byte[Convert.ToInt32(fs.Length.ToString())];
            fs.Read(imagenbyte, 0, imagenbyte.Length);
            fs.Close();
        }
    }
}


Despues que hemos codificado realizaremos una prueba para ver los efectos de nuestra programación.
Ahora comenzaremos a realizar el diseño para cargar los datos en el grid:
<DataGrid AutoGenerateColumns="False" Height="217" HorizontalAlignment="Left" Margin="12,46,0,0" Name="dgvProducto" VerticalAlignment="Top" Visibility="Visible" Width="333">
            <DataGrid.Columns>     
                <DataGridTextColumn Binding="{Binding Nombre}" Header="Nombre" IsReadOnly="True" />
                <DataGridTextColumn Binding="{Binding Precio}" Header="Precio" IsReadOnly="True" />
                <DataGridTextColumn Binding="{Binding Existencia}" Header="Existencia" IsReadOnly="True" />
                <DataGridTemplateColumn Header="Imagen" Width="SizeToCells" IsReadOnly="True" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="{Binding Imagen}" Width="100" Height="100" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

            </DataGrid.Columns>
        </DataGrid>


El Para que se realice el efecto para cargar la imagen en el grid esta en que nuestra columna donde se mostrara la imagen debe de tener un Template como se ve en el codigo XAML

En el boton mostrar datos colocamos este codigo:


Y para finalizar ejecutamos la aplicación y veremos los resultados…..

Como podemos ver se almacenado correctamente en nuestra base de datos.