w/ ef4 repo&mvc2の更新の問題 - 多くの多くのグラフを更新できません
-
16-10-2019 - |
質問
EF4を使用して、MVC2の多目的グラフを正常に更新することはできないようです。グラフ全体をクリアし、saveChanges()を呼び出してから、最後にsaveChanges()を呼び出すグラフを再構築することが最も簡単なことは、最後に再びsaveChanges()を再構築することですが、動作しません。他のすべてのプロパティ それは ただし、機能しています。まず、私のアクション方法:
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 and savegameは関連する方法です):
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();
}
}
}
私は困惑しています。
解決
ケビン、これは少し複雑であり、M:Mでは外国の鍵がなく、オブジェクトを持っていることに固執しているため、EFV1パターンに戻ってきます。
ゲームを追加すると、関係(つまり、結合テーブルの行)を追加したいのですが、単なる参照であるため、プラットフォームを追加したくありません。
私は実際にこれを行っていませんが、それを分解してから、ゲームが添付されてマークされた後にプラットフォームコレクションを再構築することができれば簡単だと思います。それ以外の場合は、グラフ全体を追加すると、すべてが追加されます。
EFの問題は、ゲームを添付すると、関連するものも添付されることです。よりクリーンなパターンがあるかもしれませんが、私の考えは、ゲームからプラットフォームを取り外し、ゲームをコンテキストに添付し、追加されたようにマークすることです。次に、プラットフォームをコンテキストに添付します。それらは「変わらない」でしょう。次に、それらをgames.platformコレクションに追加します。プラットフォームはまだ変更されませんが : 理解されます。
あなたはそれを試したかもしれません。私は自分でそれをして、何が起こっているのかを確実に見るために進むとき、すべてのエンティティの状態を見なければなりません。重要なのは、EFがそれを追跡する必要があることです 関係 追加されており、それは新しいものです(そして、結合テーブルに連続して追加されます)が、プラットフォームは新しいものではないことを理解しています。
hthジュリー