Les problèmes de mise à jour w / EF4 repo et MVC2 - ne peut pas mettre à jour un grand nombre à plusieurs graphique
-
16-10-2019 - |
Question
Je ne peux pas sembler mettre à jour avec succès un grand nombre à plusieurs graphique MVC2 en utilisant EF4. Je me suis dit la chose la plus simple à faire serait de supprimer () le graphe entier, SaveChanges d'appel (), puis reconstruire le graphique appelant SaveChanges () à nouveau à la fin, mais cela ne fonctionne pas. Toutes mes autres propriétés sont de travail, cependant. Tout d'abord, mes méthodes d'action:
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);
}
}
Le même repo (ValidateGame et SaveGame sont les méthodes appropriées):
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();
}
}
}
Je suis perplexe.
La solution
Kevin, oh c'est un peu complexe et vous refoule aux modèles EFv1 car avec M: M vous n'avez pas de clés étrangères pour appuyer et vous êtes coincé avec des objets ayant
.Lorsque vous ajoutez un jeu, vous ne voulez que la relation (à savoir une ligne dans la table de jointure) à ajouter, mais vous ne voulez pas la plate-forme à ajouter, car il est juste une référence.
Je n'ai pas vraiment fait cela, mais je pense que ce serait plus facile si vous pouviez le briser puis reconstruire la collection plates-formes une fois que le jeu est attaché et a marqué ajouté. Sinon, si vous ajoutez le graphique entier, tout est marqué ajouté.
Problème EF est que si vous attachez jeu, vous obtiendrez les choses connexes ci-joint aussi. Il pourrait y avoir un motif plus propre, mais ma pensée est de détacher les plates-formes du jeu, fixez le jeu au contexte, le marquer comme ajouté. Ensuite, j'attacher les plates-formes au contexte. Ils seront « inchangés ». Puis les ajouter à la collection de games.platform. Les plates-formes seront toujours inchangées mais le . comprendra
Vous avez sans doute essayé. Je dois le faire moi-même et regarder l'état d'entité de tout comme je vais le long pour voir à coup sûr ce qui se passe. La clé est que EF doit suivre que relation a été ajouté et qui est nouveau (et se traduira par une ligne dans la table de jointure étant ajoutée), mais comprendre que les plates-formes ne sont pas nouvelles.
HTH Julie