在我的POST编辑功能中,我的viewmodel包含我想要更新的游戏以及我想要添加到游戏中的platformId列表。
使用此代码,我能够为我的游戏添加平台,但无法删除它们。我在最后放了一个断点,肯定看到viewModel.Game.Platforms只有我选择但我的游戏列表中没有更新。
如果我添加一些平台并同时删除一些平台。添加了新平台,但没有删除。
public ActionResult Edit(GameViewModel viewModel)
{
if (ModelState.IsValid)
{
List<Platform> platforms = new List<Platform>();
foreach (var id in viewModel.PostedPlatforms.PlatformIds)
{
platforms.Add(db.Platforms.Find(Int32.Parse(id)));
}
db.Games.Attach(viewModel.Game);
viewModel.Game.Platforms = platforms;
db.Entry(viewModel.Game).State = EntityState.Modified;
UpdateModel(viewModel.Game);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel.Game);
}
模型类是
public class Game
{
public int GameId { get; set; }
public string Title { get; set; }
public List<Platform> Platforms { get; set; }
}
public class Platform
{
public int PlatformId { get; set; }
public string Name { get; set; }
public List<Game> Games { get; set; }
}
使用我们的mandave的建议,我得到了这个代码,虽然它确实改变了平台选择,但它每次都会创建一个新的游戏条目效率低下,并且还会增加内容的ID,从而弄乱书签。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(GameViewModel viewModel)
{
if (ModelState.IsValid)
{
List<Platform> platforms = new List<Platform>();
if(viewModel.PostedPlatforms != null)
{
foreach (var id in viewModel.PostedPlatforms.PlatformIds)
{
platforms.Add(db.Platforms.Find(Int32.Parse(id)));
}
}
db.Games.Remove(db.Games.Find(viewModel.Game.PostId));
db.SaveChanges();
viewModel.Game.Platforms = platforms;
db.Games.Add(viewModel.Game);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel.Game);
}
答案 0 :(得分:1)
你可以试试这个......
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(GameViewModel viewModel)
{
if (ModelState.IsValid)
{
List<Platform> selectedPlatforms = viewModel.Select(pl => GetPlatformById(pl.Id)).ToList();
var game = GetGameById(viewModel.Id);
UpdateGamePlatforms(game, selectedPlatforms);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel.Game);
}
private Platform GetPlatformById(int platformId)
{
return db.Platforms.First(pl => pl.Id == platformId);
}
private Game GetGameById(int gameId)
{
return db.Games.First(g => g.Id == gameId);
}
private void UpdateGamePlatforms(Game game, IList<Platform> selectedPlatforms)
{
var gamePlatforms = game.Platforms.ToList();
foreach (var gamePlatform in gamePlatforms)
{
if (selectedPlatforms.Contains(gamePlatform) == false)
{
game.Platforms.Remove(gamePlatform);
}
else
{
selectedPlatforms.Remove(gamePlatform);
}
}
game.Platforms.AddRange(selectedPlatforms);
}
UpdateGamePlatforms
将从游戏中移除不再选择的平台。它将离开仍然被选中的平台,并且还将为已经选择的游戏添加新的平台。
答案 1 :(得分:0)
解决方案:使用TomJerrum的解决方案,我现在可以正确编辑平台列表。要更新其余的属性,我必须映射游戏对象的所有属性,我试图编辑以匹配我的viewModel的属性。值得庆幸的是,已经有了一个函数,所以我只需要添加db.Entry(游戏).CurrentValues.SetValues(viewModel.game);.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(GameViewModel viewModel)
{
if (ModelState.IsValid)
{
List<Platform> selectedPlatforms = new List<Platform>();
if (viewModel.PostedPlatforms != null)
{
int[] platformIds = Array.ConvertAll(viewModel.PostedPlatforms.PlatformIds, p => Convert.ToInt32(p));
selectedPlatforms.AddRange(db.Platforms.Where(item => platformIds.Contains(item.PlatformId)).ToList());
}
var game = GetGameById(viewModel.Id);
UpdateGamePlatforms(game, selectedPlatforms);
db.Entry(game).CurrentValues.SetValues(viewModel.game);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel.Review);
}
private Game GetGameById(int gameId)
{
return db.Games.First(g => g.Id == gameId);
}
private void UpdateGamePlatforms(Game game, IList<Platform> selectedPlatforms)
{
var gamePlatforms = game.Platforms.ToList();
foreach (var gamePlatform in gamePlatforms)
{
if (selectedPlatforms.Contains(gamePlatform) == false)
{
game.Platforms.Remove(gamePlatform);
}
else
{
selectedPlatforms.Remove(gamePlatform);
}
}
game.Platforms.AddRange(selectedPlatforms);
}