• Sábado 20 de Abril de 2024, 13:41

Autor Tema:  Problema almacenando Blobs en C# con SQLite  (Leído 6627 veces)

marto_vil

  • Nuevo Miembro
  • *
  • Mensajes: 17
  • Nacionalidad: mx
    • Ver Perfil
Problema almacenando Blobs en C# con SQLite
« en: Domingo 6 de Noviembre de 2011, 05:35 »
0
Que tal un saludo, la situación es la siguiente, tengo creada mi BD con SQLite almacena varias variables de todo tipo int, date, varchar, las normales y hasta ahi todo funciona perfecto, el problema que tengo es que no tengo idea de como almacenar imágenes como blobs.
Lo que he intentado es poner en un formulario un botón para cargar la imagen a guardar, pero entiendo que después de esto tendría que hacer una conversión a a un arreglo de bytes y almacenar ese arreglo, pero ahi es donde entra mi duda, en el como hacerlo.
Este es mi codigo para cargar la imagen en el formulario:
#region abrir imagen
      void btn_CargarImagenClick(object sender, EventArgs e)
      {
         OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
             openFileDialog1.Filter = "Archivos de imagen(*.jpg)|*.jpg| Archivos de Imagen(*.bmp)|*.bmp|Todos los archivos (*.*)|*.*";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;
           // byte[] contenidoArchivo = File.ReadAllBytes("c:\\");
            if (openFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                string FileName = openFileDialog.FileName;
               
                imagencargada.ImageLocation = FileName.ToString();
                imagencargada.Text = FileName.ToString();
            }
            else
            {
                MessageBox.Show("No se ha podido cargar la imagen,intente de nuevo", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
      }
      #endregion

y este es el código de como hago la conexión con mi BD y almaceno mis datos:

private SQLiteConnection    conexion;               //Conexion a la BD SQLite (Clase de System.Data.SQLite)
        private SQLiteDataAdapter   db;                     //Adaptador (Clase de System.Data.SQLite)
        private DataSet             ds = new DataSet();     //DataSet
        private DataTable           dt = new DataTable();   //DataTable

void Btn_guardarClick(object sender, EventArgs e)
      {
         conectarbd();
         string strSQL = "SELECT * FROM '"+comboBox1.Text.Trim()+"'";
            db = new SQLiteDataAdapter(strSQL, conexion);
            ds.Reset();
            db.Fill(ds);

            dt = ds.Tables[0];
            DataRow dr = dt.NewRow ();
                                  
             dr["id"] = textBox7.Text;
            dr["modelo"] = textBox1.Text;
             dr["date_fecha"] = textBox2.Text;
             dr["proveedor"] = textBox3.Text;
             dr["criterio"] = textBox4.Text;
          dr["unidad_medida"] = textBox5.Text;
             dr["comentario"] = textBox6.Text;
             dr["cantidad"] = label_cantidad.Text;
                dr["color"] = label_color.text;
                                      
           dt.Rows .Add (dr);
           SQLiteCommandBuilder cb = new SQLiteCommandBuilder (db);
           cb.QuotePrefix ="[";
           cb.QuoteSuffix ="]";
           db.InsertCommand = cb.GetInsertCommand ();
           
           db.Update (dt);
           dt.AcceptChanges ();
           conexion.Close ();
           MessageBox.Show("Se ha guardado exitosamente el registro en '"+comboBox1.Text.Trim()+"'");
            limpiar();   
      }

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #1 en: Domingo 6 de Noviembre de 2011, 17:02 »
0
Que tal marto_vil, bueno empezando, para guardar campos de tipo BLOB(bytes) en una base de datos, no es igual de simple  que cuando guardar otro tipo de datos como int,varchar, etc..

Para esto tiene que almacenar en un arreglo los bytes de lo que desees enviar a tú base de datos y luego mandarselos por parámetros, por lo que ví, tú empezaste bien:

Código: C#
  1. //Está linea es correcta, debes descomentarla y poner el path correspondiente, por ejemplo: "C:\\MiImagen.jpg"
  2.  // byte[] contenidoArchivo = File.ReadAllBytes("c:\\");
  3.  

Luego tú Insert quedará de está forma (sólo es un Ejemplo):

Código: SQL
  1. INSERT INTO Tabla1 (id,nombre,IMAGEN) VALUES (1,'GABRIEL MOLINA', ?1)
  2.  

Ese ?1 significa que se lo pasarás como parámetro.

Luego para terminar a tú variable de típo SqlCommand (que llamaremos _Comando), le daremos la siguiente instrucción:
Código: C#
  1. _Comando.Parameters.Add("?1", contenidoArchivo);
  2. _Comando.ExecuteNonQuery();
  3.  


Espero te sirva,  Saludos!
@gabio87

marto_vil

  • Nuevo Miembro
  • *
  • Mensajes: 17
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #2 en: Domingo 6 de Noviembre de 2011, 20:12 »
0
Que tal, gracias por responder, pero te comento que esta parte:   // byte[] contenidoArchivo = File.ReadAllBytes("c:\\"); la tuve que dejar comentada debido a que cuando lo ejecuto así Windows me muestra un error en el que dice que no se puede cargar la imagen debido a que no soy administrador... intente encontrar una solución a ello en sangoogle pero no obtuvo resultado, así que opte por comentar dicha linea para poder cargar la imagen.
En su lugar intente algo como esto:
Código: [Seleccionar]
string ImagePath = Path.GetFullPath(openImage.FileName);
BinaryReader binaryData = new BinaryReader(new FileStream(ImagePath, FileMode.Open, FileAccess.Read));

//aqui creaba un arreglo de bytes para almacenar los datos
imageData = new byte[binaryData.BaseStream.Length];
//y aqui leia los datos dentro del arreglo
binaryData.BaseStream.Read(imageData, 0, Convert.ToInt32(binaryData.BaseStream.Length));

SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.DataSource = DatabasePath;

using(SQLiteConnection connection = new SQLiteConnection(builder.ToString()))
{
connection.Open();
using(SQLiteTransaction transaction = connection.BeginTransaction())
{
using(SQLiteCommand command = new SQLiteCommand("INSERT INTO imagenes(pictures) VALUES (@pictures)", connection, transaction)) {
try
{
command.Parameters.AddWithValue("@pictures", imageData);
command.ExecuteNonQuery();
}

catch (Exception error)
{
MessageBox.Show(error.Message.ToString());
}

finally
{
transaction.Commit();
connection.Close();
}
}
}
}

pero aun así no me funcionaba  :ayuda:

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #3 en: Lunes 7 de Noviembre de 2011, 03:14 »
0
Ahora estoy trabajando con MySQL, apenas instale SQL Server intento hacer una prueba, en la línea donde me comentas que te salio el error, si le pusiste completo el Path de donde se encuentra la imagen?, aunque bueno igual en tú código la primera parte es correcta, sin embargo nunca me he visto en la necesidad de usar el SQLiteConnectionStringBuilder por lo cuál no estoy del todo informado de que puedes o no hacer con esa clase, por cierto que error te sale?....
@gabio87

marto_vil

  • Nuevo Miembro
  • *
  • Mensajes: 17
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #4 en: Lunes 7 de Noviembre de 2011, 05:02 »
0
Realmente al poner este último código no me genera ningún error(y eso es lo extraño), simplemente no guarda el blob (que en este caso es una imagen)en la bd.

La parte de código que me da problema es esta:  // byte[] contenidoArchivo = File.ReadAllBytes("c:\\"); , la cual me decías en tu respuesta anterior que, la debería descomentar... pero como mencioné, me genera un error, concretamente este:
Citar
System.UnauthorizedAccessException: Acceso denegado a la ruta de acceso 'c:\'.
   en System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   en System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   en System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   en System.IO.File.ReadAllBytes(String path)
   en prueba_visor.inicio.Button1Click(Object sender, EventArgs e) en c:\Users\Marto\Documents\SharpDevelop Projects\prueba_visor\prueba_visor\inicio.cs:línea 79
   en System.Windows.Forms.Control.OnClick(EventArgs e)
   en System.Windows.Forms.Button.OnClick(EventArgs e)
   en System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   en System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   en System.Windows.Forms.Control.WndProc(Message& m)
   en System.Windows.Forms.ButtonBase.WndProc(Message& m)
   en System.Windows.Forms.Button.WndProc(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   en System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

y ya intenté poner otras rutas como: c:\users\documents and settings\pictures u otras donde tengo imagenes y nada, e incluso intente  con el metodo 'Fromfile' pero me resulta el mismo error... no me da acceso a leer C:\ o inlcuso otra partición de mi disco duro.

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #5 en: Lunes 7 de Noviembre de 2011, 15:52 »
0
Tienes que ponerlo así:

Código: C#
  1. byte[] contenidoArchivo = File.ReadAllBytes("c:\\users\\documents and settings\\pictures\\IMAGEN.JPG");
  2.  

Tienes que especificar una imagen...

@gabio87

marto_vil

  • Nuevo Miembro
  • *
  • Mensajes: 17
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #6 en: Martes 8 de Noviembre de 2011, 13:39 »
0
 :jumpie: si me funcionó pero...ya me perdí un poco, que pasaría entonces con la imagen que estamos poniendo como ruta, ya que al cargar la imagen me abre totalmente otra ruta (mis documentos) y cargo  "X" imagen y no la que esta especificada en mi código...

espero haberme explciado  :nosweat:

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #7 en: Martes 8 de Noviembre de 2011, 16:12 »
0
Mira lo que tú necesitas hacer entonces es usar el OpenFileDialog para que el usuario seleccione la foto que desee cargar, para eso necesitas leer aquí

http://msdn.microsoft.com/es-es/library/system.windows.forms.openfiledialog%28v=VS.80%29.aspx

Tiene un sencillo ejemplo, te recomiendo lo ejecutes y hagas OTROS ejemplos jugando con las propiedades del OpenFileDialog, tiene una propiedad que te regresa el Path de la foto que haya seleccionado, ese Path se lo vas a asignar  al File.ReadAllBytes  y Listo! :)..

Saludos.
@gabio87

marto_vil

  • Nuevo Miembro
  • *
  • Mensajes: 17
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #8 en: Martes 8 de Noviembre de 2011, 16:50 »
0
Gracias por responder, te comento que ese ejemplo ya le había echado ojo y es de ahí de donde saque la idea para hacer funcionar mi OpenFileDialog.... pero creo no le había entendido del todo porque segun a mi entender y basado en ese código es que habiá hecho lo siguiente:
Código: [Seleccionar]
string ImagePath = Path.GetFullPath(openImage.FileName);
BinaryReader binaryData = new BinaryReader(new FileStream(ImagePath, FileMode.Open, FileAccess.Read));

que fue lo que había hecho y te comentaba que no generaba error alguno pero, simplemente no guardaba la imagen...
De todas formas voy a seguir explorando como regresar el Path con el OpenFileDialog y seguiré comentando a ver que tal me fue.

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Problema almacenando Blobs en C# con SQLite
« Respuesta #9 en: Martes 8 de Noviembre de 2011, 17:06 »
0
a mi me funciona perfecto, yo uso el File.ReadAllBytes(_fileDialog.FileName)

de todas formas, puedes usar puntos de interrupción para que cheques paso a paso lo que tú aplicación hace, pero con esa línea es más que sufiente, espero ahora sí puedas terminar, saludos bye!
@gabio87