【问题标题】:Committing new data to database via EF, Errors ensue with Attaching/Adding通过 EF 将新数据提交到数据库,附加/添加会出现错误
【发布时间】:2009-09-04 15:49:24
【问题描述】:

所以我开始在我的网站 (C#) 上使用 EF,但我遇到了一些障碍。用户可以创建或修改数据,他们将通过选择屏幕(第 1 页)执行此操作。如果用户选择创建新数据,我将执行以下代码:

Program newProg = new Program();
using (DatabaseEntities context = new DatabaseEntities())
{
Guid id = new Guid(list.SelectedValue);
var itemString = from item in context.Set where item.Id == id select item;
Item selectedItem = itemString.ToList()[0];
newProg.Items.Add(selectedItem);
context.AddToProgramSet(newProg);
context.Detach(newProg);
}

几乎创建了一个新的“程序”实例,它将沿每个用户控件传递,直到用户准备好提交到数据库。此时将执行以下代码:

   using (DatabaseEntities context = new DatabaseEntities())
   {
        context.AddToProgramSet(this.SummaryControl.SelectedProgram);
        context.SaveChanges();
   }

不幸的是,当我到达那里时,我收到以下消息:

无法将对象添加到 ObjectStateManager,因为它已经有一个 EntityKey。使用 ObjectContext.Attach 附加具有现有键的对象。

在这一行:

context.AddToProgramSet(this.SummaryControl.SelectedProgram);

另外,当我在上一行之前添加以下行时:

context.Attach(this.SummaryControl.SelectedProgram);

我收到此错误:

EntityKey 值为空的对象不能附加到对象上下文。

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: asp.net entity-framework


    【解决方案1】:

    此错误的根本原因是您试图将实体添加为已设置其主键的新实体。

    在什么时候将实体添加到 SummaryControl?您的第一个代码 sn-p 显示您添加了实体:

    ...
    newProg.Items.Add(selectedItem);
    context.AddToProgramSet(newProg);
    context.Detach(newProg);
    ...
    

    然后你似乎又添加了它:

    using (DatabaseEntities context = new DatabaseEntities())
       {
            context.AddToProgramSet(this.SummaryControl.SelectedProgram);
            context.SaveChanges();
       }
    

    如果newProgthis.SummaryControl.SelectedProgram 是同一个实体,则您已尝试添加两次。从第一个 sn-p 中删除 context.AddToProgramSet(newProg);,您是否在 Entity 上工作,然后将其添加到 ProgramSet。

    【讨论】:

    • 戴夫,感谢您的回复。我注释掉了第一个 AddToProgramSet(newProg) 并收到与以前相同的错误。
    • 我要做的是在选择页面中创建一个行的新实例(在我的例子中是程序),通过用户控件传递它,沿途填充它,然后当他们到达最后一页,它获取填充的行,并将其推送到数据库。
    • 我正在与 DangerIsGo 合作。问题是否是由于我们使用 GUID 来识别我们的实体这一事实引起的?我将默认构造函数设置为为实体提供一个新的 ID GUID。这也会导致问题吗?
    • @phsr:这绝对是个问题。 EF 将假定身份来自数据库,并且不会期望在调用 SaveChanges() 时设置 ID。如果您使用的是 SQL 2005 或更高版本,请将表中的 ID 设置为 uniqueidentifier,您应该状态良好。
    【解决方案2】:

    戴夫说得对,根本原因是实体已经有一个主键。

    您没有在代码中显示的一件事是如何:

    Program newProg = new Program();
    

    变成:

    this.SummaryControl.SelectedProgram
    

    修复它的一种方法是在开始向其中添加项目之前将 newProg 保存到数据库中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-08
      • 2016-03-12
      • 1970-01-01
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多