none
Problema con BindingSource y ResultSet RRS feed

  • Pregunta

  • Hola a Todos,

    Tengo un problema y estoy estancado en el desarrollo de mi aplicacion en C# para windows mobile, estoy usando un BindingSource al que le he asociado una base de datos creada en mi aplicacion con ResultSet, consigo todo lo que necesito hacer con esta base de datos, añado registros,elimino registros, busco, etc, mi problema es que he de dar la opcion al usuario de poder cambiar la base de datos a otras existentes en el directorio del programa y no se como asociar el BindingSource a otra base de datos, ya que el DataSouce del BindingSource solo puedes asociar ResultSet creados de la base de datos y mi problema es que no se como crear el ResultSet de la base de datos seleccionada por el usuario.Como creo un ResultSet de una base de datos seleccionada??

    Gracias.

    jueves, 30 de diciembre de 2010 10:12

Respuestas

  • hola

    la verdad no he visto mucho de desarrollo mobile, pero como estas cargando este resultset, antes de asignarlo al BindingSource?

    o sea esta carga de datos la haces mediante codigo o esta automatizada por el VS, o sea arrastras y sueltas y el VS hace todo por ti

    si es esto ultimo por ahi alli este el progblema, quizas debas poner algo ams de manos en el codigo y que este no sea tan automatico, o sea carga y asigna desde codigo genrrado por ti

    asi podrias incluir la redireccion a la db seleccionada

    sino quizas debas ver de cambiar el connection string de la config de la aplciacion y reinicar el programa, o sea que se cierre y vuelva abrir para tomar la nueva conexion por los controles de form, igual esto ultimo no se que tan factuble es apciado a mobile

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 31 de diciembre de 2010 3:41
  • "Guardin" preguntó:

    > Como creo un ResultSet de una base de datos seleccionada??

    Hola:

    De la base de datos seleccionada, pocos "ResultSet" vas a crear. ;-)

    Podrás crearlos desde alguna tabla, vista, procediento almacenado o cualquier otro objeto existente en la base de datos que devuelva un conjunto de registros como resultado de ejecutar una consulta SQL de selección, por tanto, aparte de la cadena de conexión con la base de datos seleccionada por el usuario, necesitarás conocer de qué objeto vas a obtener los datos. Y todo esto, indudablemente lo vas a tener que hacer en tiempo de ejecución, si tu intención es permitirle al usuario seleccionar la base de datos y las tablas de donde va a obtener los datos.

    Suponiendo que estás trabajando con el proveedor de datos .NET para SQL Server Compact 3.5, podrías tener en tu proyecto el siguiente método para obtener un objeto DataTable:

    using System.Data.SqlServerCe;

            public DataTable GetData(string cadenaConexion, string commandText)
            {
                try
                {
                    using (SqlCeConnection cnn = new SqlCeConnection(cadenaConexion))
                    {
                        SqlCeDataAdapter da = new SqlCeDataAdapter(commandText, cnn);

                        // Añadimos información sobre la clave principal de la tabla
                        da.MissingSchemaAction = MissingSchemaAction.AddWithKey;

                        DataTable dt = new DataTable();

                        // Guardamos en el objeto DataTable la consulta SQL de
                        // selección utilizada para recuperar los datos.
                        //
                        dt.ExtendedProperties.Add("CommandText", commandText);

                        da.Fill(dt);

                        return dt;
                    }
                }
                catch (Exception)
                {
                    throw;
                }

            }

    Y éste otro para enviar las actualizaciones a la base de datos:

            public int UpdateData(string cadenaConexion, DataTable dt)
            {
                // Comprobamos los valores de los parámetros
                //
                if ((string.IsNullOrEmpty(cadenaConexion) || (dt == null)))
                {
                    throw new ArgumentNullException();
                }

                try
                {
                    // Recuperamos la consulta SQL de selección utilizada
                    // para rellenar el objeto DataTable.
                    //
                    string sql = (string) dt.ExtendedProperties["CommandText"];

                    if (string.IsNullOrEmpty(sql)) { return 0; }

                    using (SqlCeConnection cnn = new SqlCeConnection(cadenaConexion))
                    {
                        SqlCeDataAdapter da = new SqlCeDataAdapter(sql, cnn);

                        // Creamos un objeto CommandBuilder. Es necesario que la tabla
                        // tenga establecida su correspondiente clave principal.
                        //
                        SqlCeCommandBuilder cb = new SqlCeCommandBuilder(da);

                        da.InsertCommand = cb.GetInsertCommand();
                        da.UpdateCommand = cb.GetUpdateCommand();
                        da.DeleteCommand = cb.GetDeleteCommand();
                       
                        // Devolvemos los registros afectados por la actualización
                        //
                        return da.Update(dt);
                    }

                }
                catch (Exception)
                {
                   
                    throw;
                }
            }

    Cuando desees recuperar los datos, bastaría con que ejecutaras lo siguiente:

                try
                {
                    // Creamos un objeto DataTable, que se le asignaremos
                    // a la propiedad DataSource del control BindingSource.
                    //
                    bindingSource1.DataSource = GetData(CONNSTRING, "SELECT * FROM Clientes");

                    // Mostramos los datos en un control DataGridView
                    //
                    dataGridView1.DataSource = bindingSource1;

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    Por supuesto, en la variable CONNSTRING tendrás que indicar la cadena de conexión con la base de datos de SQL Server Compact 3.5 seleccionada por el usuario. Igualmente, tendrás que pasarle la consulta SQL de selección con la tabla seleccionada por el usuario, porque una veces querrá consultar la tabla Clientes y otras la tabla Facturas.

    Fíjate que le asignamos el objeto DataTable devuelto a la propiedad DataSource del control BindingSource. Esto último no sería necesario, pero lo he incluido porque parece ser que estás trabajando con un objeto BindingSource.

    Y cuando desees enviar las modificaciones a la base de datos, ejecutarías lo siguiente:

                try
                {
                    // Referenciamos el objeto DataTable asociado con el
                    // control BindingSource
                    //
                    DataTable dt = (DataTable)bindingSource1.DataSource;

                    // Actualizamos los datos
                    //
                    int n = UpdateData(CONNSTRING, dt);

                    MessageBox.Show(string.Format("Nº de registros afectados: {0}", n));

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    En principio, ésto sería lo que tendrías que ejecutar para recuperar y actualizar los datos. Adapta el ejemplo a tus necesidades.

    Un saludo y ¡Feliz Año Nuevo!

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 2 de enero de 2011 9:50
  • Saludo, en esta parte del comentario de SoftJaen,; la parte en Negrita.

    try
       {
        // Creamos un objeto DataTable, que se le asignaremos
        // a la propiedad DataSource del control BindingSource.
        //
        bindingSource1.DataSource = GetData(CONNSTRING, "SELECT * FROM Clientes");
    
        // Mostramos los datos en un control DataGridView
        //
        dataGridView1.DataSource = bindingSource1;
    
       }
       catch (Exception ex)
       {
        MessageBox.Show(ex.Message);
       }
    
    

    Puede usar las clases del espacio de nombre System.Configuration, para poder extraer los nombres de cada una da la cadena de connection que se encuentra en el archivo de configuracion y exponerselo al cliente en algun control como un ComboBoxy el valor seleccionado de este combox sera el valor de la variable CONNSTRING

    dim CONNSTRING as "calor seleccinado del combox" y luego lo pasa como argumento del metodo GetData().

    Puede extraer las cadena de connexion y retornarlo en forma de DataBinding con el codigo segte.

    ' Get the application configuration file.
    Private Function NewMethod() As BindingSource
    	Dim config As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
    
    	Dim connString As ConnectionStringSettings
    
    	Dim bs As New BindingSource()
    
    
    	Dim dic As New Dictionary(Of String, String)()
    
    	If config.ConnectionStrings.ConnectionStrings.Count > 0 Then
    		For i As Integer = 0 To config.ConnectionStrings.ConnectionStrings.Count - 1
    			connString = config.ConnectionStrings.ConnectionStrings(i)
    			If connString IsNot Nothing Then
    
    					'label1.Text += string.Format("Connection string = \"{0}\"" + "\n",
    					'  connString.Name);            
    				dic.Add(connString.Name, connString.ConnectionString)
    			Else
    
    				label1.Text += "No connection string"
    			End If
    		Next
    	End If
    	'bs.CurrentChanged += new EventHandler(bs_CurrentChanged);
    	bs.DataSource = dic
    	Return bs
    
    End Function



    Angel R. Jimenez G.
    Software Development
    Santo Domingo
    Republica Dominicana

    domingo, 2 de enero de 2011 17:34
  • "Angel Jimenez" aconsejó:

    > Puede usar las clases del espacio de nombre System.Configuration, para
    > poder extraer los nombres de cada una da la cadena de connection que
    > se encuentra en el archivo de configuracion y exponerselo al cliente
    > en algun control como un ComboBoxy el valor seleccionado de este combox
    > sera el valor de la variable CONNSTRING

    Pero, ¿es que el cliente también va a poder escribir en el archivo de configuración de la aplicación, concretamente, en el elemento <connectionStrings> </connectionStrings>? Para ello, tendría que darle soporte a la aplicación para poder escribir en el archivo XML de configuración.

    Si estamos hablando de un simple archivo de SQL Server Compact 3.5, pienso que con seleccionar la ruta donde se encuentre físicamente el archivo es más que suficiente para construir la cadena de conexión, y esto lo puede obtener de la propiedad FileName de la clase OpenFileDialog.

    ¿Que el archivo tiene una contraseña? Si la escribe en el archivo XML de configuración, digo yo que tendrá que codificarla, mayormente por motivos de seguridad. En cambio, una vez seleccionada la base de datos, puede mostrar un cuadro de diálogo para que el usuario introduzca la contraseña.

    Un saludo y ¡Feliz Año Nuevo!

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 2 de enero de 2011 18:09
  • Saludo Henriquez Feliz Navidad, no es que el cliente tenga que escribir en el archivo de configuracion, sino mas bien darle un poco de flexibilidad a la aplicacion para que el cliente puede leer del archivo de configuracion las connexiones que tiene disponoble y poder conectarse a una o a otra base de datos, segun los requerimientos de Guardin.

    >Guardin dijo:

    mi problema es que he de dar la opcion al usuario de poder cambiar la base de datos a otras existentes en el directorio del programa y no se como asociar el BindingSource a otra base de datos,

     

     

     



    Angel R. Jimenez G.
    Software Development
    Santo Domingo
    Republica Dominicana
    domingo, 2 de enero de 2011 18:34
  • "Angel Jimenez" escribió:

    > no es que el cliente tenga que escribir en el archivo de configuracion, sino
    > mas bien darle un poco de flexibilidad a la aplicacion para que el cliente
    > puede leer del archivo de configuracion las connexiones que tiene disponoble
    > y poder conectarse a una o a otra base de datos, ...

    ¡Hasta ahí podíamos llegar!, permitir que el usuario escriba directamente en el archivo de configuración de la aplicación. :-))

    Por eso he dicho que «tendría que darle soporte a la aplicación para poder escribir en el archivo XML de configuración».

    > Guardin dijo:
    >
    > mi problema es que he de dar la opcion al usuario de poder cambiar
    > la base de datos a otras existentes en el directorio del programa

    Pues más fácil aún, no necesita utilizar la clase OpenFileDialog. Si todos los archivos de datos están en el mismo directorio del programa, del archivo ejecutable, conforme recorre el directorio va añadiendo al control ListBox, ComboBox o al que crea conveniente, los archivos con una extensión concreta, que para los archivos de SQL Server Compact será la extensión *.sdf. Y especificar el parámetro Data Source de la cadena de conexión, creo que es cuestión de "coser y cantar".

    > Saludo Henriquez

    Por cierto, mi nombre es sin H y Z: Enrique a secas. :-)

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 2 de enero de 2011 18:55

Todas las respuestas

  • hola

    la verdad no he visto mucho de desarrollo mobile, pero como estas cargando este resultset, antes de asignarlo al BindingSource?

    o sea esta carga de datos la haces mediante codigo o esta automatizada por el VS, o sea arrastras y sueltas y el VS hace todo por ti

    si es esto ultimo por ahi alli este el progblema, quizas debas poner algo ams de manos en el codigo y que este no sea tan automatico, o sea carga y asigna desde codigo genrrado por ti

    asi podrias incluir la redireccion a la db seleccionada

    sino quizas debas ver de cambiar el connection string de la config de la aplciacion y reinicar el programa, o sea que se cierre y vuelva abrir para tomar la nueva conexion por los controles de form, igual esto ultimo no se que tan factuble es apciado a mobile

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 31 de diciembre de 2010 3:41
  • "Guardin" preguntó:

    > Como creo un ResultSet de una base de datos seleccionada??

    Hola:

    De la base de datos seleccionada, pocos "ResultSet" vas a crear. ;-)

    Podrás crearlos desde alguna tabla, vista, procediento almacenado o cualquier otro objeto existente en la base de datos que devuelva un conjunto de registros como resultado de ejecutar una consulta SQL de selección, por tanto, aparte de la cadena de conexión con la base de datos seleccionada por el usuario, necesitarás conocer de qué objeto vas a obtener los datos. Y todo esto, indudablemente lo vas a tener que hacer en tiempo de ejecución, si tu intención es permitirle al usuario seleccionar la base de datos y las tablas de donde va a obtener los datos.

    Suponiendo que estás trabajando con el proveedor de datos .NET para SQL Server Compact 3.5, podrías tener en tu proyecto el siguiente método para obtener un objeto DataTable:

    using System.Data.SqlServerCe;

            public DataTable GetData(string cadenaConexion, string commandText)
            {
                try
                {
                    using (SqlCeConnection cnn = new SqlCeConnection(cadenaConexion))
                    {
                        SqlCeDataAdapter da = new SqlCeDataAdapter(commandText, cnn);

                        // Añadimos información sobre la clave principal de la tabla
                        da.MissingSchemaAction = MissingSchemaAction.AddWithKey;

                        DataTable dt = new DataTable();

                        // Guardamos en el objeto DataTable la consulta SQL de
                        // selección utilizada para recuperar los datos.
                        //
                        dt.ExtendedProperties.Add("CommandText", commandText);

                        da.Fill(dt);

                        return dt;
                    }
                }
                catch (Exception)
                {
                    throw;
                }

            }

    Y éste otro para enviar las actualizaciones a la base de datos:

            public int UpdateData(string cadenaConexion, DataTable dt)
            {
                // Comprobamos los valores de los parámetros
                //
                if ((string.IsNullOrEmpty(cadenaConexion) || (dt == null)))
                {
                    throw new ArgumentNullException();
                }

                try
                {
                    // Recuperamos la consulta SQL de selección utilizada
                    // para rellenar el objeto DataTable.
                    //
                    string sql = (string) dt.ExtendedProperties["CommandText"];

                    if (string.IsNullOrEmpty(sql)) { return 0; }

                    using (SqlCeConnection cnn = new SqlCeConnection(cadenaConexion))
                    {
                        SqlCeDataAdapter da = new SqlCeDataAdapter(sql, cnn);

                        // Creamos un objeto CommandBuilder. Es necesario que la tabla
                        // tenga establecida su correspondiente clave principal.
                        //
                        SqlCeCommandBuilder cb = new SqlCeCommandBuilder(da);

                        da.InsertCommand = cb.GetInsertCommand();
                        da.UpdateCommand = cb.GetUpdateCommand();
                        da.DeleteCommand = cb.GetDeleteCommand();
                       
                        // Devolvemos los registros afectados por la actualización
                        //
                        return da.Update(dt);
                    }

                }
                catch (Exception)
                {
                   
                    throw;
                }
            }

    Cuando desees recuperar los datos, bastaría con que ejecutaras lo siguiente:

                try
                {
                    // Creamos un objeto DataTable, que se le asignaremos
                    // a la propiedad DataSource del control BindingSource.
                    //
                    bindingSource1.DataSource = GetData(CONNSTRING, "SELECT * FROM Clientes");

                    // Mostramos los datos en un control DataGridView
                    //
                    dataGridView1.DataSource = bindingSource1;

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    Por supuesto, en la variable CONNSTRING tendrás que indicar la cadena de conexión con la base de datos de SQL Server Compact 3.5 seleccionada por el usuario. Igualmente, tendrás que pasarle la consulta SQL de selección con la tabla seleccionada por el usuario, porque una veces querrá consultar la tabla Clientes y otras la tabla Facturas.

    Fíjate que le asignamos el objeto DataTable devuelto a la propiedad DataSource del control BindingSource. Esto último no sería necesario, pero lo he incluido porque parece ser que estás trabajando con un objeto BindingSource.

    Y cuando desees enviar las modificaciones a la base de datos, ejecutarías lo siguiente:

                try
                {
                    // Referenciamos el objeto DataTable asociado con el
                    // control BindingSource
                    //
                    DataTable dt = (DataTable)bindingSource1.DataSource;

                    // Actualizamos los datos
                    //
                    int n = UpdateData(CONNSTRING, dt);

                    MessageBox.Show(string.Format("Nº de registros afectados: {0}", n));

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    En principio, ésto sería lo que tendrías que ejecutar para recuperar y actualizar los datos. Adapta el ejemplo a tus necesidades.

    Un saludo y ¡Feliz Año Nuevo!

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 2 de enero de 2011 9:50
  • Saludo, en esta parte del comentario de SoftJaen,; la parte en Negrita.

    try
       {
        // Creamos un objeto DataTable, que se le asignaremos
        // a la propiedad DataSource del control BindingSource.
        //
        bindingSource1.DataSource = GetData(CONNSTRING, "SELECT * FROM Clientes");
    
        // Mostramos los datos en un control DataGridView
        //
        dataGridView1.DataSource = bindingSource1;
    
       }
       catch (Exception ex)
       {
        MessageBox.Show(ex.Message);
       }
    
    

    Puede usar las clases del espacio de nombre System.Configuration, para poder extraer los nombres de cada una da la cadena de connection que se encuentra en el archivo de configuracion y exponerselo al cliente en algun control como un ComboBoxy el valor seleccionado de este combox sera el valor de la variable CONNSTRING

    dim CONNSTRING as "calor seleccinado del combox" y luego lo pasa como argumento del metodo GetData().

    Puede extraer las cadena de connexion y retornarlo en forma de DataBinding con el codigo segte.

    ' Get the application configuration file.
    Private Function NewMethod() As BindingSource
    	Dim config As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
    
    	Dim connString As ConnectionStringSettings
    
    	Dim bs As New BindingSource()
    
    
    	Dim dic As New Dictionary(Of String, String)()
    
    	If config.ConnectionStrings.ConnectionStrings.Count > 0 Then
    		For i As Integer = 0 To config.ConnectionStrings.ConnectionStrings.Count - 1
    			connString = config.ConnectionStrings.ConnectionStrings(i)
    			If connString IsNot Nothing Then
    
    					'label1.Text += string.Format("Connection string = \"{0}\"" + "\n",
    					'  connString.Name);            
    				dic.Add(connString.Name, connString.ConnectionString)
    			Else
    
    				label1.Text += "No connection string"
    			End If
    		Next
    	End If
    	'bs.CurrentChanged += new EventHandler(bs_CurrentChanged);
    	bs.DataSource = dic
    	Return bs
    
    End Function



    Angel R. Jimenez G.
    Software Development
    Santo Domingo
    Republica Dominicana

    domingo, 2 de enero de 2011 17:34
  • "Angel Jimenez" aconsejó:

    > Puede usar las clases del espacio de nombre System.Configuration, para
    > poder extraer los nombres de cada una da la cadena de connection que
    > se encuentra en el archivo de configuracion y exponerselo al cliente
    > en algun control como un ComboBoxy el valor seleccionado de este combox
    > sera el valor de la variable CONNSTRING

    Pero, ¿es que el cliente también va a poder escribir en el archivo de configuración de la aplicación, concretamente, en el elemento <connectionStrings> </connectionStrings>? Para ello, tendría que darle soporte a la aplicación para poder escribir en el archivo XML de configuración.

    Si estamos hablando de un simple archivo de SQL Server Compact 3.5, pienso que con seleccionar la ruta donde se encuentre físicamente el archivo es más que suficiente para construir la cadena de conexión, y esto lo puede obtener de la propiedad FileName de la clase OpenFileDialog.

    ¿Que el archivo tiene una contraseña? Si la escribe en el archivo XML de configuración, digo yo que tendrá que codificarla, mayormente por motivos de seguridad. En cambio, una vez seleccionada la base de datos, puede mostrar un cuadro de diálogo para que el usuario introduzca la contraseña.

    Un saludo y ¡Feliz Año Nuevo!

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 2 de enero de 2011 18:09
  • Saludo Henriquez Feliz Navidad, no es que el cliente tenga que escribir en el archivo de configuracion, sino mas bien darle un poco de flexibilidad a la aplicacion para que el cliente puede leer del archivo de configuracion las connexiones que tiene disponoble y poder conectarse a una o a otra base de datos, segun los requerimientos de Guardin.

    >Guardin dijo:

    mi problema es que he de dar la opcion al usuario de poder cambiar la base de datos a otras existentes en el directorio del programa y no se como asociar el BindingSource a otra base de datos,

     

     

     



    Angel R. Jimenez G.
    Software Development
    Santo Domingo
    Republica Dominicana
    domingo, 2 de enero de 2011 18:34
  • "Angel Jimenez" escribió:

    > no es que el cliente tenga que escribir en el archivo de configuracion, sino
    > mas bien darle un poco de flexibilidad a la aplicacion para que el cliente
    > puede leer del archivo de configuracion las connexiones que tiene disponoble
    > y poder conectarse a una o a otra base de datos, ...

    ¡Hasta ahí podíamos llegar!, permitir que el usuario escriba directamente en el archivo de configuración de la aplicación. :-))

    Por eso he dicho que «tendría que darle soporte a la aplicación para poder escribir en el archivo XML de configuración».

    > Guardin dijo:
    >
    > mi problema es que he de dar la opcion al usuario de poder cambiar
    > la base de datos a otras existentes en el directorio del programa

    Pues más fácil aún, no necesita utilizar la clase OpenFileDialog. Si todos los archivos de datos están en el mismo directorio del programa, del archivo ejecutable, conforme recorre el directorio va añadiendo al control ListBox, ComboBox o al que crea conveniente, los archivos con una extensión concreta, que para los archivos de SQL Server Compact será la extensión *.sdf. Y especificar el parámetro Data Source de la cadena de conexión, creo que es cuestión de "coser y cantar".

    > Saludo Henriquez

    Por cierto, mi nombre es sin H y Z: Enrique a secas. :-)

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 2 de enero de 2011 18:55