none
Guardar cambios en un grid WPF 4 EF RRS feed

  • Pregunta

  • Buenos días:

    Estoy empezando con mi primera aplicación en WPF y he estado durante una semana informándome un poco cómo funcionan EF y WPF. Más o menos lo tengo claro y me he puesto a hacer pruebas. Sigo este ejemplo: http://msdn.microsoft.com/es-es/site/dd465158, y me funciona a la perfección, pero quiero poner un botón que me guarde los datos que haya modificado en el grid (en especial lo que quiero es permitir que el usuario añada líneas a los pedidos y los pueda guardar).

    El código que pongo en el botón es:

        Private Sub btnGuardar_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnGuardar.Click
            Dim AdventureWorksLTEntities As AdventureWorksOrdersViewer.AdventureWorksLTEntities = New AdventureWorksOrdersViewer.AdventureWorksLTEntities()
            AdventureWorksLTEntities.AcceptAllChanges()
            AdventureWorksLTEntities.SaveChanges()
        End Sub

    Y está claro que algún concepto no he comprendido muy bien, porque cuando detengo la aplicación y la vuelvo a ejecutar, compruebo que no se han guardado los datos.

     

    ¿Alguien podría aclararme un poco los conceptos? ¿qué es lo que hago mal?

     

     

    Gracias

     

    viernes, 8 de julio de 2011 9:40

Respuestas

  • Hola Carlos.

    Entity framework puede ser desde lo mas sencillo hasta lo mas complicado de usar, dependiendo de como se implementen las soluciones.

    En el link que has puesto, es un ejemplo sencillo que crea VS mediante asistentes, los asistentes solo se tienen que tomar de ejemplo y modificar el codigo en consecuencia segun la arquitectura que se quiera seguir.

    En este caso y como dices que estas empezando, no quiero liarte mucho, tan solo comentarte que en entity framework no hay que perder de vista el contexto de datos, ya que es este objeto el nucleo de todo y el que va a mantener el almacen de datos locales. Si este objeto se pierde, se tiene que volver a crear, obtener de nuevo los datos, modificarlos y actualizarlos.

    Bien, en el codigo tuyo se te tiene que haber creado algo asi:

          WpfApplication6.AdventureWorksLT2008R2Entities adventureWorksLT2008R2Entities = new WpfApplication6.AdventureWorksLT2008R2Entities();
          // Cargar datos en SalesOrderHeader. Puede modificar este código según sea necesario.
          System.Windows.Data.CollectionViewSource salesOrderHeaderViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("salesOrderHeaderViewSource")));
          System.Data.Objects.ObjectQuery<WpfApplication6.SalesOrderHeader> salesOrderHeaderQuery = this.GetSalesOrderHeaderQuery(adventureWorksLT2008R2Entities);
          salesOrderHeaderViewSource.Source = salesOrderHeaderQuery.Execute( System.Data.Objects.MergeOption.AppendOnly); 
    

    Este codigo esta en el evento Loaded de la ventana, de modo que una vez establecida la fuente de datos en el gridView, el contexto se pierde 'adventureWorksLT2088R2', este objeto es el que mantiene todo el almacen de datos de las consultas que se hagan sobre el, como he comentado si se pierde su referencia se tiene que volver a crear.

    Lo mas facil que tienes para actualizar y seguir probando con tu ejemplo seria lo siguiente (seguro que ya lo has adivinado). Se trata de sacar la linea con el contexto de datos y establecerla como variable privada:

    private WpfApplication6.AdventureWorksLT2008R2Entities adventureWorksLT2008R2Entities = new WpfApplication6.AdventureWorksLT2008R2Entities();
    

    de modo que ya tienes una referencia al contexto en todo momento, asi luego tan solo tienes que hacer en tu evento:

    adventureWorksLT2008R2Entities.SaveChanges();
    

    y cualquier dato que hayas modificado, sera modificado en la BBDD.

    NOTA: esto es a modo de ejemplo, dependiendo de la solucion, es posible que no sea conveniente mantener una referencia al contexto, ya que ocupa recursos (y no pocos), por eso veras cosas como en el link que ha puesto el compañero Jonathan que el contexto es creado mediante un USING, de modo que es destruido al finalizar la clausula. Esto ya depende de ti.

    Para finalizar te dejo un link que implementa casi un CRUD con entityframeword y un datagrid para que tengas un ejemplo mas:

    http://www.dotnetcurry.com/ShowArticle.aspx?ID=563

     


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/
    • Marcado como respuesta Carlos Adrián lunes, 11 de julio de 2011 6:25
    sábado, 9 de julio de 2011 11:13

Todas las respuestas

  • Hola Carlos Adrian

    te dejo esta pagina de MSDN donde hablan sobre el alta, baja y cambio con EF.

    espero que te sirva de mucho

    http://msdn.microsoft.com/es-es/library/ff686135.aspx

    saludos



    Si la respuesta te fue útil recuerda marcarla como respusta o útil.
    Jonathan S. Romero Jimenez
    Especialista .Net

    Profesional Microsoft VIP
    MCTS ASP.Net 3.5
    DCE 3a Estrella

    • Propuesto como respuesta David_González sábado, 9 de julio de 2011 9:40
    viernes, 8 de julio de 2011 16:57
  • Hola Carlos.

    Entity framework puede ser desde lo mas sencillo hasta lo mas complicado de usar, dependiendo de como se implementen las soluciones.

    En el link que has puesto, es un ejemplo sencillo que crea VS mediante asistentes, los asistentes solo se tienen que tomar de ejemplo y modificar el codigo en consecuencia segun la arquitectura que se quiera seguir.

    En este caso y como dices que estas empezando, no quiero liarte mucho, tan solo comentarte que en entity framework no hay que perder de vista el contexto de datos, ya que es este objeto el nucleo de todo y el que va a mantener el almacen de datos locales. Si este objeto se pierde, se tiene que volver a crear, obtener de nuevo los datos, modificarlos y actualizarlos.

    Bien, en el codigo tuyo se te tiene que haber creado algo asi:

          WpfApplication6.AdventureWorksLT2008R2Entities adventureWorksLT2008R2Entities = new WpfApplication6.AdventureWorksLT2008R2Entities();
          // Cargar datos en SalesOrderHeader. Puede modificar este código según sea necesario.
          System.Windows.Data.CollectionViewSource salesOrderHeaderViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("salesOrderHeaderViewSource")));
          System.Data.Objects.ObjectQuery<WpfApplication6.SalesOrderHeader> salesOrderHeaderQuery = this.GetSalesOrderHeaderQuery(adventureWorksLT2008R2Entities);
          salesOrderHeaderViewSource.Source = salesOrderHeaderQuery.Execute( System.Data.Objects.MergeOption.AppendOnly); 
    

    Este codigo esta en el evento Loaded de la ventana, de modo que una vez establecida la fuente de datos en el gridView, el contexto se pierde 'adventureWorksLT2088R2', este objeto es el que mantiene todo el almacen de datos de las consultas que se hagan sobre el, como he comentado si se pierde su referencia se tiene que volver a crear.

    Lo mas facil que tienes para actualizar y seguir probando con tu ejemplo seria lo siguiente (seguro que ya lo has adivinado). Se trata de sacar la linea con el contexto de datos y establecerla como variable privada:

    private WpfApplication6.AdventureWorksLT2008R2Entities adventureWorksLT2008R2Entities = new WpfApplication6.AdventureWorksLT2008R2Entities();
    

    de modo que ya tienes una referencia al contexto en todo momento, asi luego tan solo tienes que hacer en tu evento:

    adventureWorksLT2008R2Entities.SaveChanges();
    

    y cualquier dato que hayas modificado, sera modificado en la BBDD.

    NOTA: esto es a modo de ejemplo, dependiendo de la solucion, es posible que no sea conveniente mantener una referencia al contexto, ya que ocupa recursos (y no pocos), por eso veras cosas como en el link que ha puesto el compañero Jonathan que el contexto es creado mediante un USING, de modo que es destruido al finalizar la clausula. Esto ya depende de ti.

    Para finalizar te dejo un link que implementa casi un CRUD con entityframeword y un datagrid para que tengas un ejemplo mas:

    http://www.dotnetcurry.com/ShowArticle.aspx?ID=563

     


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/
    • Marcado como respuesta Carlos Adrián lunes, 11 de julio de 2011 6:25
    sábado, 9 de julio de 2011 11:13
  • Ante todo quiero agradeceros a los dos vuestras respuestas. Una vez entendido que el contexto no debo perderlo, ahora se me presenta otro problema. David, cuando lo pruebo tal y como me comentas, me sale el siguiente error "No se controló UpdateException". Si no me equivoco eso es porque estoy haciendo el update de los datos que he metido en el datagrid, pero lógicamente no he especificado las foreign keys, porque esas columnas no se muestran.

    Al no haber un evento OnAddNew ni nada parecido, ya que no se programa directamente contra el grid, sino contra los EF que van por debajo del mismo, ¿cómo puedo detectar cuando se añade un registro al grid para poder dar valores a los campos que no se muestran en el mismo?

    No sé si me he explicado muy bien...

     

    Un saludo y muchas gracias de nuevo.


    Carlos Adrián Martínez
    lunes, 11 de julio de 2011 6:25