更新Entity Framework 4.1中的FK关系

时间:2012-05-16 08:11:38

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

我想我已阅读过有关此内容的每篇文章和堆栈溢出问题,但无法解决问题。让我从我的模型开始

public class Entry
{
    public Entry ()
    {
        DateEntered = DateTime.Now;
    }

    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [Required]
    public string Email { get; set; }
    public string Number { get; set; }
    public string FbId { get; set; }
    [ReadOnly(true)]
    public DateTime DateEntered { get; set; }
    public string AccessToken { get; set; }

    //Relationsips
    public Backgrounds Background { get; set; }
    public Cars Car { get; set; }
}

public class Backgrounds
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Filename { get; set; }
}

public class Cars
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FileName { get; set; }
}

现在在我的控制器中,我正在更新条目。如下所示

    // PUT /api/entries/5
    public HttpResponseMessage Put(Entry entry)
    {
        if(ModelState.IsValid)
        {

            _db.Entries.Attach(entry);
            _db.Entry(entry).State = EntityState.Modified;
            _db.SaveChanges();

            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }

        throw new HttpResponseException(HttpStatusCode.BadRequest);
    }

我的条目模型正确更新,但是如果例如entry.Background.Name发生更改,则不会将其保留到数据库中。我的控制器正在接受整个条目模型,包括其关系=>背景和汽车。但是,不会更新或反映更改为关系的任何值。任何优雅的解决方案,而无需查询数据库然后更新?我不希望在更新之前有任何额外的查询或查询。

由于

泰龙

1 个答案:

答案 0 :(得分:0)

您必须手动告知EF有关对象图所做的所有更改。您告诉EF关于更改入口实例但您没有告诉它有关相关实体或关系本身的任何更改。没有优雅的方法来解决这个问题。您通常有两种选择:

  • 您将使用一些DTO而不是您的实体,这些DTO将有一些标记,如IsDirty - 当您将对象图返回到控制器时,您将从DTO重建实体并根据{{1}设置其状态}。此解决方案需要进一步扩展,例如,如果您的客户端也可以删除关系。
  • 您将从数据库查询对象图并将传入的更改合并到从数据库检索的实体。

有一些部分解决方案,例如强制保存对所有相关对象的更改,方法是将其状态设置为已修改并通过IsDirty识别新对象,但这些解决方案仅适用于特定情况。

关于此问题的更复杂discussion