我试图更新模型,但得到错误"操作失败:由于一个或多个外键属性不可为空,因此无法更改关系。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。"
根据我对The relationship could not be changed because one or more of the foreign-key properties is non-nullable的理解,问题可能在于实体框架如何处理我的虚拟ICollection
但是,在使用scaffolded存储库模式时,我并不确定如何实现该解决方案。我是否必须编辑Save() - 方法ParentObjectRepository-class?
实际上我真的认为必须有某种方法让EF理解这一点。我无法看到EF团队的想法和#34;可能没有人使用具有外键约束的对象集合,不能支持"。
更新 添加了代码
[HttpPost]
public ActionResult Edit(int id, FormCollection formCollection)
{
var eventRepository = new MagnetEventRepository();
var original = eventRepository.Find(id);
UpdateModel(original);
eventRepository.Save();
return RedirectToAction("Details", "Home", new { slug = original.Slug });
}
public void Save()
{
context.SaveChanges();
}
更多代码:
public class MagnetEvent
{
public virtual int Id { get; set; }
[Required]
public virtual string Name { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm}")]
[DataType(DataType.DateTime)]
public virtual DateTime? StartDate { get; set; }
public virtual string Description { get; set; }
[StringLength(100)]
public virtual string Slug { get; set; }
public virtual int MaximumCapacity { get; set; }
[DataType(DataType.Currency)]
public virtual int TicketPrice { get; set; }
public virtual int LocationId { get; set; }
public virtual Location Location { get; set; }
public virtual Collection<Ticket> Tickets { get; set; }
public virtual Collection<AttendeeInformationField> CaptureAttendeeInformationFields { get; set; }
public virtual int CustomerId { get; set; }
[Required]
public virtual CUSTOMER Customer { get; set; }
}
Save() - 方法来自MagnetEventRepository,它来自上面的类。
另一次更新 我通过将AttendeeInformationField中的MagnetEventId更改为nullable int来成功删除了错误。在检查数据库时,我可以确切地看到错误。
假设我有一个单独的AttendeeInformationField,其值为&#34;电子邮件&#34;。当我编辑我的MagnetEvent时,AttendeeInformationField将MagnetEventId更新为null,然后使用正确的MagnetEventId和Value添加一个新帖子。
我非常喜欢AttendeeInformationField中的帖子而不是更新。
答案 0 :(得分:0)
可以为事件对象添加代码吗?你称之为原创的那个。
可能是因为UpdateModel更改了关联对象的一些信息,如果是这样,那就不好了。不确定这一点虽然我看不到所有的代码。
我更喜欢不使用UptadeModel,而是使用inputmodel或MVC模型作为参数,并手动将chages映射到加载的原始对象。
Antoher问题是我看不清楚 eventRepository.Save();
真的做了SaveShages吗?可以?我可以在另一种方法Save?
中查看一些上下文代码答案 1 :(得分:0)
正如例外情况所说,它会像您的关联集合或其他相关对象一样找不到有效的ID值。
您是否急于加载相关对象?喜欢顾客?
答案 2 :(得分:0)
有一点值得注意的是,由于您的FK不可为空,因此您不应该将客户的[必需]作为推断。如果模型中没有FK,则必须仅在导航属性上使用。
要尝试诊断问题,可以加载对象并在调试器中查看它,您应该期望locationId和CustomerId都具有非零值。
答案 3 :(得分:0)
我找到了解决问题的方法。当涉及到UpdateModel和包含ICollection的模型时,它似乎是ASP.NET MVC中的一个错误(?)。
解决方案是覆盖默认行为,如本博文中所述:http://www.codetuning.net/blog/post/Binding-Model-Graphs-with-ASPNETMVC.aspx
<强>更新强> 我找到了解决方案!以上仅在更新集合中的现有项目时才有效。要解决这个问题,我必须手动检查并添加新的AttendeeInformationFields。像这样:
[HttpPost]
public ActionResult Edit(int id, MagnetEvent magnetEvent)
{
var eventRepository = new MagnetEventRepository();
var original = eventRepository.Find(id);
UpdateModel(original);
foreach (var attendeeInformationField in magnetEvent.CaptureAttendeeInformationFields)
{
var attendeeInformationFieldId = attendeeInformationField.Id;
if (original.CaptureAttendeeInformationFields.AsQueryable().Where(ai => ai.Id == attendeeInformationFieldId).Count() == 0)
{
original.CaptureAttendeeInformationFields.Add(attendeeInformationField);
}
}
eventRepository.Save();
}
与修改后的DefaultModelBinder一起,这实际上适用于编辑和添加。现在我还没有尝试删除。
不过,我希望有一种更简单的方法可以做到这一点。看起来像很多编码来完成一项非常基本的任务。