C# DataGridView AllowUserToAddressRow属性不';行不通

C# DataGridView AllowUserToAddressRow属性不';行不通,c#,linq,entity-framework,datagridview,bindingsource,C#,Linq,Entity Framework,Datagridview,Bindingsource,我有一个带有实体框架的简单项目,在我的表单中有一个DataGridView,我将其allowUserToAddress属性设置为true,但仍然无法向其中添加新行 这是我的代码: DBEntities context = new DBEntities(); private void Form1_Load(object sender, EventArgs e) { var q = (from i in context.myTable select i).ToLis

我有一个带有实体框架的简单项目,在我的
表单中有一个
DataGridView
,我将其
allowUserToAddress
属性设置为
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()
在数据库文件中不插入任何内容后,使用这种方法。所以我想这可能与这个问题有关,
DataGridView
with
true
allowUserToAddressRow
属性不允许我在
DataGridView

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

您的问题是调用
.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;
}
我尝试了这个方法,它可以很好地允许新行(表中确实需要有主键,但无论如何都应该有主键)


请注意:在实体框架4.1-


我在回答中说应该,因为事实上我有点惊讶它这么容易。我记得它在Entity Framework的早期版本中工作得不太好,我也没有太多地使用过4.0

如果上述解决方案不起作用,则您可能必须以艰难的方式完成此操作,并在保存之前自己添加新对象:

首先引入一个绑定源,在保存时执行以下操作(示例中使用一个虚构的Customer实体):


我刚刚痛苦地从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();为了保存更改或插入,我遇到了一个与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;
var tableList=\u dbImplementation.SelectAll().ToList();
var bindingSource=新的bindingSource();
bindingSource.DataSource=typeof(表A);
foreach(表列表中的变量tableA)
{
bindingSource.Add(表a);
}
dataGridView.DataSource=bindingSource;

有用的参考资料:

@masoudkeshavarz我将在我的回答中写一个例子这不是真的-DataGridView的设计允许用户使用UI向绑定的数据源添加行,事实上这可能是控件的最标准用法。是的,我完全同意你的看法。但是,即使用户添加行,您仍然希望更新带下划线的数据结构,因为dataGridView将自动反映该更改。非常感谢。问题在于
ToList()
方法。我删除了
ToList()
方法,现在它可以很好地处理插入或删除操作。但如果在
DataGridView
中有自动递增(pk)列,它仍然会在插入时抛出异常。您对如何处理该异常有何建议?@masoudkeshavarz您的意思是您的数据库表有一个自动递增标识列作为主键?这对我来说很好。例外情况是什么?最好将此作为一个新问题提问。
更新条目时出错。有关详细信息,请参见内部异常。
好吧,我在新问题中问它。非常感谢:)@masoudkeshavarz很棒-在您发布问题(包括内部异常)后,我或其他人应该能够提供帮助。您应该再次检查的一点是,模型是最新的。刷新它,看看这是否仍然发生。另外-如果在代码中向上下文添加项,会发生什么情况?然后是否可以插入?是的,我可以在代码中插入项。在代码中,我将(pk)留空,SQLServer理解它的自动增量。但在
DataGridView
中,它似乎试图将0值作为(pk)插入,但它不理解它是自动递增的
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;