ASP MVC如何使用collections字段更新DB条目

时间:2012-08-18 17:02:40

标签: asp.net-mvc model-view-controller binding model

对于下面附带的示例,如何正确保存更新的模型?我害怕像自定义模型绑定等一些疯狂的东西。我想用优雅来解决这个问题。

模型

public class Artist     {
    public int ArtistId { get; set; }
    public string ArtistName { get; set; }
    public virtual ICollection<Album> ArtistAlbums { get; set; }
}

public class Album     {
    public int AlbumId { get; set; }
    public string AlbumName { get; set; }
}

创建视图中的代码段

<input type="text" name="ArtistAlbums" />
<input type="text" name="ArtistAlbums" />

这是Create Actio n

public ActionResult Create(Artist newArtist, IEnumerable<string> ArtistAlbums)     {
    foreach (var album in ArtistAlbums)         {
      newArtist.ArtistAlbums.Add(new Album { AlbumName = album });
    }
    db.Entry(newArtist).State = EntityState.Added;
    db.SaveChanges();
    return RedirectToAction("Index");
}

以下是我的编辑视图

@foreach (var album in Model.ArtistAlbums)    {
    <div>@album.AlbumName</div>
    <input type="text" name="ArtistAlbums" />
}

以下是我的编辑操作

[HttpPost]
public ActionResult Edit(Artist artist, IEnumerable<string> ArtistAlbums)  {
    foreach (var album in ArtistAlbums)         {
      artist.ArtistAlbums.Add(new Album { AlbumName = album });
    }
    // An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
    //db.Entry(artist).State = EntityState.Modified;

    // this one update my Artist entry, but not my Albums for this entry.
    // var oldArtist = db.Artists.Find(artist.ArtistId);
    // db.Entry(oldArtist).CurrentValues.SetValues(artist);
    db.SaveChanges();
    return RedirectToAction("Index");
}

2 个答案:

答案 0 :(得分:0)

在您的编辑操作中:

ArtistAlbums.ToList().ForEach(album=>artist.ArtistAlbums.Add(new Album { AlbumName = album }));
    db.Artists.Attach(artist);
    db.ObjectStateManager.ChangeObjectState(artist,EntityState.Modified);
    db.SaveChanges();

答案 1 :(得分:0)

试试这个......评论中的解释

[HttpPost]
public ActionResult Edit(Artist artist, IEnumerable<string> ArtistAlbums)
{
    // First detach the object with same key
    Artist tbd = db.Artists.Find(artist.Id);
    ((IObjectContextAdapter)db).ObjectContext.Detach(tbd);

    foreach (var album in ArtistAlbums)
    {
      artist.ArtistAlbums.Add(new Album { AlbumName = album });
    }

    // The above error should not occur now.
    db.Entry(artist).State = EntityState.Modified;
    db.SaveChanges();

    return RedirectToAction("Index");
}