0

我正在尝试更新模型,但收到错误“操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性设置为空值,如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,否则必须删除不相关的对象。”

据我了解,关系无法改变,因为一个或多个外键属性不可为空,问题可能出在实体框架如何处理我的虚拟 ICollection

但是,我不确定在使用脚手架存储库模式时如何实现该解决方案。我是否必须编辑 Save() 方法 ParentObjectRepository 类?

其实我真的认为一定有办法让EF理解这一点。我看不出 EF 团队是如何思考“可能没有人使用具有外键约束的对象集合,我们不支持”。

更新 添加的代码

[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 更改为可为空的 int 成功消除了错误。在检查数据库时,我可以确切地看到问题所在。

假设我有一个值为“E-mail”的 AttendeeInformationField。当我编辑我的 MagnetEvent 时,AttendeeInformationField 将 MagnetEventId 更新为 null,然后添加具有正确 MagnetEventId 和值的新帖子。

如果更新了 AttendeeInformationField 中的帖子,我会非常喜欢。

4

4 回答 4

0

你可以为你的事件对象添加代码吗?你称之为原创的那个。

可能是因为 UpdateModel 更改了相关对象的一些信息,如果是这样,那就不好了。虽然我看不到所有代码,但不确定这一点。

我更喜欢不使用 UptadeModel,而是使用 inputmodel 或您的 MVC 模型作为参数,并手动将 chages 映射到加载的原始对象。

另一个问题是我看不到 eventRepository.Save();

真的做一个SaveShages吗?可以?我可以用另一种方法保存一些上下文代码吗?

于 2012-04-16T07:50:46.983 回答
0

正如例外所说,它看起来像您的关联集合或其他关联对象无法找到有效的 ID 值。

您是否急切地加载关联的对象?喜欢客户?

于 2012-04-16T08:19:31.167 回答
0

需要注意的一件事是,您不应该在 Customer 上有 [Required],因为它是从您的 FK 不可为空这一事实推断出来的。如果模型中没有 FK,则只应在导航属性上使用 required。

要尝试诊断问题,您是否可以加载对象并在调试器中查看它,您应该期望 locationId 和 CustomerId 都具有非零值。

于 2012-04-16T09:53:54.837 回答
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 一起,这实际上适用于编辑和添加。目前我还没有尝试删除。

不过,我希望有一种更简单的方法来做到这一点。似乎需要大量编码来完成一项非常基本的任务。

于 2012-04-17T06:58:07.473 回答