Using C# to connect Entity Framework objects to a Datagridview

c# data-binding datagridview entity-framework winforms

Question

I've been attempting to connect an Entity Framework object to a DataGridView, but I keep running into roadblocks and can't seem to locate the solution anywhere.

I can make modifications and save them back to the database by binding the whole table (entity) to a gridview as seen below:

    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();
    }

However, I tried doing it this way since I didn't want to display all of the columns from the table in my DB in my datagridview.

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();
    }

Now, however, I am unable to update any data in my DataGridView.

I'm losing my mind since I can't see the forest for the trees in this situation. Could someone kindly show me how wrong I am or explain me what the best practices are for binding EF with Winforms?

It seems to relate to the following section:

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

But I'm not sure why.

1
32
4/26/2011 4:56:44 PM

Accepted Answer

The issue with the sentence:

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

An type anonymous is being created, and because anonymous types are read-only and immutable, this is true. Because of this, neither the new type nor the old EF object reflects your modifications.

I've included three alternatives below for you to prevent all of the columns of the object you are binding to from being shown.

Hiding undesirable columns

Setting the visible attribute to false for the columns you don't want to display is the simplest strategy.

dataGridView1.Columns[0].Visible = false;

Where the value in the Columns collection indexer may either be a string for the column name or an integer giving the position of the column.

EF's unique object for this databinding

You could also take care of this at the EF layer by creating a special object for your binding that EF extracts from the database but leaves out the columns you don't want. Although I haven't actually used EF 4.0, I know that it now has this capabilities.

Projecting a custom DTO from an EF object, then mapping it back

The third choice (which, in my view, ranges from good to poor, but I thought I'd share a few strategies with you nonetheless!) is to do a concrete type query before mapping it back to an EF object. the following

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();
}

That may also be a practical option in certain circumstances.

38
1/13/2012 11:43:50 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow