【问题标题】:DataGridView AllowUserToAddRow property doesn't workDataGridView AllowUserToAddRow 属性不起作用
【发布时间】:2012-08-03 16:26:21
【问题描述】:

我有一个使用 Entity Framework 的简单项目,我的 Form 中有一个 DataGridView,我将其 AllowUserToAddRow 属性设置为 true,但我仍然无法向其中添加新行。

这是我的代码:

DBEntities context = new DBEntities();
private void Form1_Load(object sender, EventArgs e)
{
    var q = (from i in context.myTable
             select i).ToList();
    DataGridView.DataSource = q;
}

private void btnSave_Click(object sender, EventArgs e)
{
    context.SaveChanges();
    MessageBox.Show("saved successfully");
}

如果我使用BindingSource 控件,它允许我在DataGridView 中插入行,但是在我调用context.SaveChanges() 之后,我的数据库文件中没有插入任何内容。所以我认为可能与这个问题有关的是DataGridViewtrue AllowUserToAddRow 属性不允许我在DataGridView 中插入行。

【问题讨论】:

    标签: c# linq entity-framework datagridview bindingsource


    【解决方案1】:

    您的问题是您调用 .ToList() 并具体化您的查询 - 这似乎破坏了完整的数据绑定。

    应该能够简单地拥有:

    DBEntities context = new DBEntities();
    private void Form1_Load(object sender, EventArgs e)
    {
        var q = (from i in context.myTable
                 select i);
        DataGridView.DataSource = q;
    }
    

    我试过这个,它可以很好地允许新行(你的表中确实需要有一个主键,但无论如何你应该有)。


    注意:此行为已在 Entity Framework 4.1 - Webforms data binding with EF Code-First Linq query error

    中被故意破坏

    我在回答中说应该,因为实际上我有点惊讶它这么容易。我记得它在早期版本的 Entity Framework 中运行得不是很好,而且我没有经常使用 4.0。

    如果上述解决方案不起作用,您可能不得不在保存之前自己添加新对象:

    首先引入一个绑定源,然后在保存时执行类似的操作(在示例中使用假想的 Customer 实体):

    foreach (Customer customer in bs.List)
    {         
        // In my db customerId was an identity column set as primary key
        if (customer.CustomerId == 0)
            context.Customers.AddObject(customer);
    }
    context.SaveChanges();
    

    【讨论】:

    • 非常感谢。问题出在ToList() 方法上。我删除了ToList() 方法,现在它可以很好地用于插入或删除。但是,如果您的 DataGridView 中有自动增量 (pk) 列,它仍然会在插入时引发异常。您对如何处理该异常有什么建议吗?
    • @masoudkeshavarz 你的意思是你的数据库表有一个自增标识列作为主键?这对我来说很好。有什么例外?可能最好将此作为一个新问题提出。
    • An error occurred while updating the entries. See the inner exception for details. 好吧,我在新问题中问它。非常感谢:)
    • @masoudkeshavarz 太好了 - 一旦您发布问题(包括内部异常),我自己或其他人应该能够提供帮助,您应该仔细检查的一件事是模型是最新的。刷新它,看看是否仍然发生这种情况。另外 - 如果你在代码中将项目添加到上下文中会发生什么,你可以插入吗?
    • 是的,我可以在代码中插入项目。在代码中,我将 (pk) 留空,SQL SERVER 了解它的自动增量。但是在DataGridView 中,它似乎尝试将 0 值插入为 (pk) 并且它不明白它是自动递增的
    【解决方案2】:

    我刚刚痛苦地从 4 升级到 EF 6,我遇到了类似的问题,EF6 中的解决方案如下,我已经展示了 where 语句以获得进一步的帮助。

    DBEntities context = new DBEntities();
    private void Form1_Load(object sender, EventArgs e)
    {
      context.MyTable.Where(e => e.myField == 1).Load();
    
      BindingSource bs = new BindingSource();
      bs.DataSource = context.MyTable.Local.ToBindingList();
      myDatagridView.DataSource = bs;
    }
    

    您现在可以使用 context.SaveChanges();保存更改或插入

    【讨论】:

      【解决方案3】:

      我在 Interbase 方言的自定义数据库实现中遇到了类似的问题。 我的解决方案与上面的类似:

      var tableAList = _dbImplementation.SelectAll<TableA>().ToList();
      var bindingSource = new BindingSource();
      bindingSource.DataSource = typeof (TableA);
      foreach (var tableA in tableAList)
      {
          bindingSource.Add(tableA);
      }
      dataGridView.DataSource = bindingSource;
      

      有用的参考:A Detailed Data Binding Tutorial

      【讨论】:

        【解决方案4】:

        如果您要将 dataGridView 绑定到源,则插入行的唯一适当方法是将行添加到 DataGridView 绑定到的数据结构中。

        【讨论】:

        • @masoudkeshavarz 我会在我的回答中写一个例子
        • 这不是真的 - DataGridView 旨在允许用户使用 UI 向绑定的数据源添加行,实际上这可能是控件的最标准用法。
        • 真的,我完全同意你的看法。但是,即使用户添加了一行,您仍然希望更新带下划线的数据结构,因为 dataGridView 会自动反映该更改。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-06
        • 1970-01-01
        • 2011-03-31
        • 2018-11-19
        • 2012-07-23
        • 2016-07-16
        • 2020-01-24
        相关资源
        最近更新 更多