Problemi durante l'aggiornamento w / EF4 repo & MVC2 - non può aggiornare molti-a-molti grafico

StackOverflow https://stackoverflow.com/questions/4764370

Domanda

non riesco ad aggiornare con successo una relazione molti-a-molti grafico in MVC2 utilizzando EF4. Ho pensato che la cosa più semplice da fare sarebbe quella di Clear () l'intero grafico, SaveChanges call (), quindi rigenerare il grafico chiamare SaveChanges () di nuovo alla fine, ma non funziona. Tutte le mie altre proprietà a lavorare, però. In primo luogo, i miei metodi di azione:

    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);
        }
    }

Il pronti contro termine in sé (ValidateGame e SaveGame sono i metodi rilevanti):

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();
        }
    }
}

stumped.

È stato utile?

Soluzione

Kevin, oh, questo è un po 'complessa e ti costringe di nuovo a modelli EFv1 perché con M: M non si dispone di chiavi esterne a cui appoggiarsi e si sono bloccati con avere gli oggetti

.

Quando si aggiunge un gioco, si vuole la relazione (vale a dire una riga della tabella join) da aggiungere, ma non si vuole la piattaforma da aggiungere in quanto è solo un riferimento.

Non ho effettivamente fatto questo, ma penso che sarebbe più facile se si potesse rompere lo distingue e quindi rigenerare la collezione piattaforme volta che il gioco è collegato e contrassegnato aggiunto. In caso contrario, se si aggiunge l'intero grafico, tutto viene contrassegnato aggiunto.

problema con EF è che se si collega gioco otterrete la roba relativo allegato troppo. Ci potrebbe essere un modello più pulito ma il mio pensiero è quello di staccare le piattaforme dal gioco, attaccare il gioco al contesto, segnare come aggiunto. Poi vorrei collegare le piattaforme al contesto. Saranno "invariato". Poi aggiungere alla collezione games.platform. Le piattaforme saranno ancora invariato, ma il :. si capirà

Si può avere provato questo. Avrei dovuto farlo io stesso e guardare lo stato dell'entità di tutto come vado avanti per vedere di sicuro di quello che sta accadendo. La chiave è che EF ha bisogno di tenere traccia che un rapporto è stato aggiunto e che c'è di nuovo (e si tradurrà in una riga nel join tabella che viene aggiunto), ma capire che le piattaforme non sono nuovi.

hth Julie

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top