32 votos

Vinculando los objetos del Marco de Entidades a un Datagridview C#

He intentado vincular un objeto de Entity Framework a un DataGridView pero sigo encontrando callejones sin salida y no encuentro mi respuesta en ninguna parte.

Puedo unir toda una tabla (entidad) a una vista de cuadrícula y me permitirá hacer cambios y guardar esos cambios en la base de datos de esta manera:

    WS_Model.WS_Entities context;

    private void simpleButton1_Click(object sender, EventArgs e)
    {
        context = new WS_Entities();

        var query = from c in context.Users select c;

        var users = query.ToList();

        gridControl1.DataSource = users;
    }

    private void simpleButton2_Click(object sender, EventArgs e)
    {
        context.SaveChanges();
    }

pero no quiero ver todas las columnas de la tabla de mi base de datos en mi vista de datos, así que intenté hacerlo de esta manera...

WS_Entities context = new WS_Entities();

    private void simpleButton1_Click(object sender, EventArgs e)
    {
        var query = from c in context.Users
                    where c.UserName == "James"
                    select new { c.UserName, c.Password, c.Description };

        var results = query.ToList();

        gridControl1.DataSource = results;
    }

    private void simpleButton2_Click(object sender, EventArgs e)
    {
        context.SaveChanges();
    }

pero ahora no puedo editar ningún dato en mi DataGridView.

No puedo ver el bosque por los árboles aquí - por favor, ¿a alguien le importaría señalarnos el error de mi camino o decirme cuáles son las mejores prácticas para unir EF con Winforms ya que estoy teniendo una fuga de cerebros.

Puedo ver que tiene que ver con la sección:

select new { c.UserName, c.Password, c.Description }

Pero no sé por qué.

38voto

David Hall Puntos 17450

El problema con la línea:

select new { c.UserName, c.Password, c.Description }

es que está creando un tipo anónimo y los tipos anónimos son inmutables, eso es sólo lectura. Por eso sus cambios no se reflejan ni en el nuevo tipo ni en el objeto EF original.

Ahora, en cuanto a las formas de no mostrar todas las columnas del objeto al que se está vinculando, he dado tres opciones a continuación.

Ocultar las columnas no deseadas

El enfoque más directo es establecer la propiedad visible como falsa para las columnas que no quieres mostrar.

dataGridView1.Columns[0].Visible = false;

El valor del indexador de la colección Columnas puede ser un entero que especifica la ubicación de la columna o una cadena para el nombre de la columna.

Objeto personalizado en EF para esta base de datos

También puedes manejar esto en la capa EF - creando un objeto personalizado para tu encuadernación que EF mapea desde la base de datos sin las columnas que no quieres. En realidad no he usado EF 4.0 pero entiendo que ahora tiene esta capacidad.

DTO personalizado proyectado desde el objeto EF y luego mapeado de vuelta

La tercera opción (y estos van de bueno a malo en mi opinión de ellos, pero pensé en contarles algunos enfoques!) es hacer una consulta a un tipo concreto y luego mapear de vuelta al objeto EF. Algo así como:

private class DataBindingProjection
{
    public string UserName { get; set; };
    public string Password { get; set; };
    public string Description { get; set; };
}

private void simpleButton1_Click(object sender, EventArgs e)
{
    context = new WS_Entities();
    var query = from c in context.Users
                where c.UserName == "James"
                select new DataBindingProjection { UserName = c.UserName, Password = c.Password, Description = c.Description };
    var users = query.ToList();
    gridControl1.DataSource = users;
}

private void simpleButton2_Click(object sender, EventArgs e) 
{
    // and here you have some code to map the properties back from the 
    // projection objects to your datacontext

    context.SaveChanges();
}

En ciertas situaciones que también podrían ser una solución viable...

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X