实体框架 - 使用导航属性编辑多个实体

时间:2016-01-26 09:50:45

标签: c# asp.net-mvc entity-framework sql-update

我几天以来一直在为我的问题寻找解决方案。我对实体框架比较陌生,只是习惯了它。

这是我的问题:

我在ASP.NET MVC中创建了一个Web API。在API中的一种方法中,我需要更新多个现有记录(相同类型的实体)。该实体具有以下结构:

预约

  • GUID(PK)
  • 名称(接口的约会名称)
  • Team_Creation_FK
  • Team_Editing_FK
  • Team_Delivery_FK
  • Team_Creation(导航属性)
  • Team_Editing(导航属性)
  • Team_Delivery(导航属性)

此实体可以在不同的部分(创建,编辑,创建)中包含相同的团队。例如,Team_Creation和Team_Editing列可以包含相同的团队(团队:测试(例如))。

所以更新多个记录的方法如下:

    public IHttpActionResult EditAppointment(IEnumerable<Appointment> appointments)
    {
        foreach(Appointment appointment in appointments)
        {
            appointment.Team_Creation_FK = appointment.Team_Creation != null ? appointment.Team_Creation.GUID: (Guid?)null;                
            appointment.Team_Editing_FK = appointment.Team_Editing != null ? appointment.Team_Editing.GUID: (Guid?)null;
            appointment.Team_Delivery_FK = appointment.Team_Delivery != null ? appointment.Team_Delivery.GUID: (Guid?)null;           

            db.Entry(appointment).State = EntityState.Modified;                
        }

        db.SaveChanges();

        return Ok();
    }

但是当我尝试在不同实体中更新具有相同团队的实体时,我收到以下错误:

  

类型&#39; System.InvalidOperationException&#39;的例外情况发生在EntityFramework.dll中但未在用户代码中处理。附加信息:附加类型为&#39; Orderus.Models.Team&#39;的实体。失败,因为同一类型的另一个实体已具有相同的主键值。使用&#39;附加&#39;方法或将实体的状态设置为“未更改”#39;或者&#39;修改&#39;如果图中的任何实体具有冲突的键值。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,请使用&#39;添加&#39;方法或“添加”#39;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者&#39;修改&#39;酌情。

为什么将导航属性附加到dbContext?或者我在错误的地方寻找?我该如何解决这个问题?

感谢您的帮助,我感谢任何帮助!

更新

课程预约

public partial class Appointment
{
    public System.Guid GUID { get; set; }
    public string Name{ get; set; }
    public Nullable<System.Guid> Team_Creation_FK { get; set; }
    public Nullable<System.Guid> Team_Editing_FK { get; set; }
    public Nullable<System.Guid> Team_Delivery_FK { get; set; }

    public virtual Team Team_Creation { get; set; }
    public virtual Team Team_Editing { get; set; }
    public virtual Team Team_Delivery { get; set; }
}

1 个答案:

答案 0 :(得分:1)

假设约会实体不是新的并且团队已经存在,问题是你有很多Team对象的实例与我相同。它们代表相同的团队,但是是不同的实例。

因此,当您附加约会时,EF会附加所有对象图并找到具有相同ID的N Team对象。

解决方案:设置相应的团队Guid后设置appointment.Team_xx = null。或者甚至更好,只需预约团队guid而不是完整的图表并节省网络流量。