删除和添加相关对象时的实体框架InvalidOperationException

时间:2018-04-06 09:32:01

标签: entity-framework entity-framework-6

我得到了

  

System.InvalidOperationException:'操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。'

运行下一个代码时:

using (var context = new entities.Model1())
{
  var entity = context.MeetingActivities
    .Include(i => i.Participants)
    .Single(m => m.ActivityId == 424);

  // this way delete actually works
  //int[] participantList = entity.Participants.Select(p => p.Id).ToArray();
  //List<entities.Participant> list = context.Participants.Where(p => participantList.Contains(p.Id)).ToList();
  //context.Participants.RemoveRange(list);

  // delete all participants, doesn't work
  while (entity.Participants.Count > 0)
  {
    entity.Participants.Remove(entity.Participants.First());
  }

  // insert new participant
  entity.Participants.Add(new entities.Participant()
  {
    Participant_DisplayName = "testName",
    MeetingActivityId = entity.Id,
    ParticipantId = 4111
  });

  context.SaveChanges();
}

MeetingActivity与参与者之间的关系是一对多在一次会议上可以有一个或多个参与者。参与者表格包含下一栏:

  • Id(自动增量)
  • ParticipantId(表客户的外键)
  • Participant_DisplayName(因此我们在展示参与者时不要加入)
  • MeetingActivityId(表MeetingActivity的外键)

为什么不从实体中删除工作? entity.Participants.Remove(entity.Participants.First()); ..实体框架是跟踪实体因此它应该发出删除和插入?实际插入是发布的。但如果entity.Participants.Add发出sql insert语句,为什么entity.Participants.Remove不会发出删除语句?

我必须提到,当某些记录在参与者表格中时会发生这种情况。

1 个答案:

答案 0 :(得分:0)

想象一下下一个场景:

using (var context = new entities.Model1())
{
  // participants are not included - .Include(i => i.Participants)
  var entity = context.MeetingActivities.Single(m => m.ActivityId == 424);

  // as entity.Participants is empty collection, if object state should
  // reflect the one in db, context.SaveChanges() would result next query:
  // delete from dbo.Participant where MeetingActivityId = x as
  // entity.Participants is empty collection.
  // Therefore it makes sense to use context.Participants.Remove/RemoveRange
  context.SaveChanges();
}

示例结论:对象状态无法反映db中的变化。