2011-01-21 69 views
0

我似乎無法使用EF4成功更新MVC2中的多對多圖。我認爲最簡單的做法是清除()整個圖形,調用SaveChanges(),然後在最後重建調用SaveChanges()的圖形,但它不起作用。然而,我的所有其他屬性ARE正在工作。首先,我的操作方法:更新瓦特/ EF4回購&MVC2的問題 - 無法更新多對多的圖

public ActionResult EditReview(int id) 
    { 
     var game = _gameRepository.GetGame(id); 
     var genres = _gameRepository.AllGenres(); 
     var platforms = _gameRepository.AllPlatforms(); 

     var model = new AdminGameViewModel { GameData = game, AllGenres = genres, AllPlatforms = platforms }; 

     return View(model); 
    } 

    // 
    // POST: /Admin/EditReview/5 

    [HttpPost] 
    public ActionResult EditReview([Bind(Prefix="GameData")]Game existingGame, int[] PlatformIDs) 
    { 
     try 
     { 
      _gameRepository.ValidateGame(existingGame, PlatformIDs); 
     } 
     catch(RulesException ex) 
     { 
      ex.CopyTo(ModelState); 
      ex.CopyTo(ModelState, "GameData"); 
     } 

     if (ModelState.IsValid) 
     { 
      return RedirectToAction("Index"); 
     } 
     else 
     { 
      var genres = _gameRepository.AllGenres(); 
      var platforms = _gameRepository.AllPlatforms(); 

      var model = new AdminGameViewModel { GameData = existingGame, AllGenres = genres, AllPlatforms = platforms }; 

      return View(model); 
     } 
    } 

回購自身(ValidateGame和遊戲存檔的相關方法):

namespace HandiGamer.Domain.Concrete 
{ 
    public class HGGameRepository : IGameRepository 
    { 
     private HGEntities _siteDB = new HGEntities(); 

     public List<Game> Games 
     { 
      get { return _siteDB.Games.ToList(); } 
     } 

     public void ValidateGame(Game game, int[] PlatformIDs) 
     { 
      var errors = new RulesException<Game>(); 

      if (string.IsNullOrEmpty(game.GameTitle)) 
      { 
       errors.ErrorFor(x => x.GameTitle, "A game must have a title"); 
      } 

      if (string.IsNullOrEmpty(game.ReviewText)) 
      { 
       errors.ErrorFor(x => x.ReviewText, "A review must be written"); 
      } 

      if (game.ReviewScore <= 0 || game.ReviewScore > 5) 
      { 
       errors.ErrorFor(x => x.ReviewScore, "A game must have a review score, and the score must be between 1 and 5"); 
      } 

      if (string.IsNullOrEmpty(game.Pros)) 
      { 
       errors.ErrorFor(x => x.Pros, "Each game review must have a list of pros"); 
      } 

      if (string.IsNullOrEmpty(game.Cons)) 
      { 
       errors.ErrorFor(x => x.Cons, "Each game review must have a list of cons"); 
      } 

      if (PlatformIDs == null || PlatformIDs.Length == 0) 
      { 
       errors.ErrorForModel("A game must belong to at least one platform"); 
      } 

      if (game.GenreID == 0) 
      { 
       errors.ErrorFor(x => x.GenreID, "A game must be associated with a genre"); 
      } 

      if (errors.Errors.Any()) 
      { 
       throw errors; 
      } 
      else 
      { 
       SaveGame(game, PlatformIDs); 
      } 
     } 

     public void SaveGame(Game game, int[] PlatformIDs) 
     { 
      _siteDB.Games.Attach(game); 

      if (game.GameID > 0) 
      { 
       _siteDB.ObjectStateManager.ChangeObjectState(game, System.Data.EntityState.Modified); 

       game.Platforms.Clear(); 
      } 
      else 
      { 
       _siteDB.ObjectStateManager.ChangeObjectState(game, System.Data.EntityState.Added); 
      } 

      foreach (int id in PlatformIDs) 
      { 
       Platform plat = _siteDB.Platforms.Single(pl => pl.PlatformID == id); 
       game.Platforms.Add(plat); 
      } 

      game.LastModified = DateTime.Now; 

      _siteDB.SaveChanges(); 
     } 

     public Game GetGame(int id) 
     { 
      return _siteDB.Games.Include("Genre").Include("Platforms").SingleOrDefault(g => g.GameID == id); 
     } 

     public IEnumerable<Game> GetGame(string title) 
     { 
      return _siteDB.Games.Include("Genre").Include("Platforms").Where(g => g.GameTitle.StartsWith(title)).AsEnumerable<Game>(); 
     } 

     public List<Game> GetGamesByGenre(int id) 
     { 
      return _siteDB.Games.Where(g => g.GenreID == id).ToList(); 
     } 

     public List<Game> GetGamesByGenre(string genre) 
     { 
      return _siteDB.Games.Where(g => g.Genre.Name == genre).ToList(); 
     } 

     public List<Game> GetGamesByPlatform(int id) 
     { 
      return _siteDB.Games.Where(g => g.Platforms.Any(p => p.PlatformID == id)).ToList(); 
     } 

     public List<Game> GetGamesByPlatform(string platform) 
     { 
      return _siteDB.Games.Where(g => g.Platforms.Any(p => p.Name == platform)).ToList(); 
     } 

     public List<Genre> AllGenres() 
     { 
      return _siteDB.Genres.OrderBy(g => g.Name).ToList(); 
     } 

     public List<Platform> AllPlatforms() 
     { 
      return _siteDB.Platforms.OrderBy(p => p.PlatformID).ToList(); 
     } 
    } 
} 

我難倒。

回答

1

Kevin, 哦,這有點複雜,並且強制您回到EFv1模式,因爲使用M:M您沒有外鍵可以依靠,並且您堅持擁有對象。

當您添加遊戲時,您希望添加關係(即連接表中的行),但您不希望平臺被添加,因爲它只是一個參考。

我還沒有真正做到這一點,但我認爲如果你可以將它拆開,然後在遊戲連接並標記添加後重建平臺集合,那將會更容易。否則,如果添加整個圖形,則會添加標記。

EF的問題在於,如果你附加遊戲,你也會得到相關的東西。可能有更清晰的模式,但我的想法是將遊戲平臺從遊戲中分離出來,將遊戲附加到上下文中,將其標記爲已添加。然後我會將平臺附加到上下文。他們將「不變」。然後將它們添加到games.platform集合中。這些平臺仍將保持不變,但會被理解爲

您可能已經嘗試過。我必須親自去做,並隨時觀察所有事物的實體狀態,以確定發生了什麼。關鍵是EF需要跟蹤關係已被添加,這是新的(並且會導致添加連接表中的一行),但要明白平臺不是新的。

心連心 朱莉

+0

聽起來不錯,但我不知道如何安裝/從遊戲脫離平臺。智能感知不給我任何提示。 – 2011-01-24 20:53:51