将实体框架对象绑定到Datagridview C#

Jim*_*mes 32 c# data-binding entity-framework datagridview winforms

我一直在尝试将一个Entity Framework对象绑定到一个DataGridView,但我一直在追求死胡同,我似乎无法在任何地方找到我的答案.

我可以将整个表(实体)绑定到gridview,它将允许我进行更改并将这些更改保存回DB,如下所示:

    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();
    }
Run Code Online (Sandbox Code Playgroud)

但我不想在我的数据库视图中查看数据库中表格中的所有列,所以我尝试这样做...

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();
    }
Run Code Online (Sandbox Code Playgroud)

但现在我无法编辑DataGridView中的任何数据.

我不能在这里看到木头的树木 - 请有人介意指出我的方式的错误或告诉我将EF与Winforms绑定的最佳实践是什么,因为我正在耗尽人才.

我可以看到它与该部分有关:

select new { c.UserName, c.Password, c.Description }
Run Code Online (Sandbox Code Playgroud)

但我不知道为什么.

Dav*_*all 38

该行的问题:

select new { c.UserName, c.Password, c.Description }
Run Code Online (Sandbox Code Playgroud)

它是创建一个匿名类型,匿名类型是不可变的 - 这是只读的.这就是为什么您的更改不会反映在新类型或原始EF对象中的原因.

现在,至于没有显示您绑定的对象的所有列的方法,我在下面给出了三个选项.

隐藏不需要的列

最直接的方法是将您不想显示的列的visible属性设置为false.

dataGridView1.Columns[0].Visible = false;
Run Code Online (Sandbox Code Playgroud)

其中Columns集合索引器中的值可以是指定列位置的整数,也可以是列名称的字符串.

EF中的自定义对象用于此数据绑定

您也可以在EF层处理此问题 - 为您的绑定创建一个自定义对象,EF从数据库映射而不使用您不想要的列.我根本没有使用EF 4.0,但我知道它现在有这个功能.

自定义DTO从EF对象投射,然后映射回来

第三种选择(在我看来,这些选择从好到坏,但我想我会告诉你一些方法!)是查询具体类型然后映射回EF对象.就像是:

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();
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,这也可能是一个可行的解决方案......

  • @David Hall:您如何将此解决方案转换为在MVVM中使用?我正在尝试将其用于ObservableCollection,以便我可以通知PropertyChanged事件.谢谢! (2认同)