Vincular objetos de Entity Framework a un Datagridview C#


He estado tratando de vincular un objeto Entity Framework a un DataGridView, pero sigo llegando a callejones sin salida y parece que no puedo encontrar mi respuesta en ningún lugar.

Puedo enlazar la totalidad de una tabla (entidad) a un gridview y me permitirá hacer cambios y guardar esos cambios en la base de datos de la siguiente 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 en mi base de datos en mi datagridview, 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 la madera de los árboles aquí - por favor, alguien le importaría señalar nuestro error de mis caminos o decirme cuáles son las mejores prácticas para atar EF con Winforms como estoy recibiendo 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é.

Author: David Hall, 2011-04-26

1 answers

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, es decir, de solo lectura. Esta es la razón por la que 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 está enlazando, he dado tres opciones a continuación.

Ocultar columnas no deseadas

El enfoque más directo es establecer el visible propiedad a false para las columnas que no desea mostrar.

dataGridView1.Columns[0].Visible = false;

Donde el valor en el indexador de colección de columnas puede ser un entero que especifique la ubicación de la columna o una cadena para el nombre de la columna.

Objeto personalizado en EF para este databinding

También puede manejar esto en la capa EF - creando un objeto personalizado para su enlace que EF mapea desde la base de datos sin las columnas que no desea. No he utilizado EF 4.0 en absoluto realmente pero yo entiende que tiene esta capacidad ahora.

DTO personalizado proyectado desde el objeto EF y luego mapeado

La tercera opción (y estos van de bueno a malo en mi opinión de ellos, pero pensé que te diría algunos enfoques!) es consultar a un tipo concreto y luego mapear de nuevo al objeto EF. Algo 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 podría ser una solución viable también...

 38
Author: David Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-13 11:43:50