Asp.net mvc 2 更新EF4回购和;MVC2-can';t更新多对多图
我似乎无法使用EF4成功更新MVC2中的多对多图。我认为最简单的方法是清除()整个图形,调用SaveChanges(),然后在最后再次调用SaveChanges()重新构建图形,但它不起作用。但是,我的所有其他属性都在运行。首先,我的行动方法:Asp.net mvc 2 更新EF4回购和;MVC2-can';t更新多对多图,asp.net-mvc-2,entity-framework-4,updating,Asp.net Mvc 2,Entity Framework 4,Updating,我似乎无法使用EF4成功更新MVC2中的多对多图。我认为最简单的方法是清除()整个图形,调用SaveChanges(),然后在最后再次调用SaveChanges()重新构建图形,但它不起作用。但是,我的所有其他属性都在运行。首先,我的行动方法: public ActionResult EditReview(int id) { var game = _gameRepository.GetGame(id); var genres = _gameRepo
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和SaveGame是相关方法):
namespace HandiGamer.Domain.Concrete
{
公共类HGGameRepository:IGameRepository
{
私有HGEntities_siteDB=新HGEntities();
公开名单游戏
{
获取{return_siteDB.Games.ToList();}
}
public void ValidateGame(游戏,int[]平台)
{
var errors=新规则异常();
if(string.IsNullOrEmpty(game.GameTitle))
{
errors.ErrorFor(x=>x.GameTitle,“游戏必须有标题”);
}
if(string.IsNullOrEmpty(game.ReviewText))
{
errors.ErrorFor(x=>x.ReviewText,“必须编写审查”);
}
如果(game.ReviewScore 5)
{
errors.ErrorFor(x=>x.ReviewScore,“一个游戏必须有一个回顾分数,分数必须在1到5之间”);
}
if(string.IsNullOrEmpty(game.Pros))
{
errors.ErrorFor(x=>x.Pros,“每个游戏评论都必须有一个Pros列表”);
}
if(string.IsNullOrEmpty(game.Cons))
{
errors.ErrorFor(x=>x.Cons,“每个游戏回顾必须有一个Cons列表”);
}
if(PlatformIDs==null | | PlatformIDs.Length==0)
{
errors.ErrorForModel(“一个游戏必须至少属于一个平台”);
}
如果(game.GenreID==0)
{
errors.ErrorFor(x=>x.GenreID,“一个游戏必须与一个流派相关联”);
}
if(errors.errors.Any())
{
抛出错误;
}
其他的
{
SaveGame(游戏,平台);
}
}
公共void SaveGame(游戏,int[]平台)
{
_siteDB.Games.Attach(游戏);
如果(game.GameID>0)
{
_siteDB.ObjectStateManager.ChangeObjectState(game、System.Data.EntityState.Modified);
game.Platforms.Clear();
}
其他的
{
_siteDB.ObjectStateManager.ChangeObjectState(game、System.Data.EntityState.Added);
}
foreach(PlatformIDs中的int-id)
{
平台平台=_siteDB.Platforms.Single(pl=>pl.PlatformID==id);
游戏。平台。添加(平台);
}
game.LastModified=DateTime.Now;
_SaveChanges();
}
公共游戏GetGame(int id)
{
return _siteDB.Games.Include(“流派”).Include(“平台”).SingleOrDefault(g=>g.GameID==id);
}
公共IEnumerable GetGame(字符串标题)
{
return _siteDB.Games.Include(“流派”).Include(“平台”).Where(g=>g.GameTitle.StartsWith(title)).AsEnumerable();
}
公共列表GetGamesByGenre(内部id)
{
return _siteDB.Games.Where(g=>g.GenreID==id.ToList();
}
公开列表GetGamesByGenre(字符串类型)
{
return _siteDB.Games.Where(g=>g.Genre.Name==Genre.ToList();
}
公共列表GetGamesByPlatform(int id)
{
return _siteDB.Games.Where(g=>g.Platforms.Any(p=>p.PlatformID==id)).ToList();
}
公共列表GetGamesByPlatform(字符串平台)
{
return _siteDB.Games.Where(g=>g.Platforms.Any(p=>p.Name==platform)).ToList();
}
公共列表所有类型()
{
return_siteDB.Genres.OrderBy(g=>g.Name.ToList();
}
公共列表所有平台()
{
return _siteDB.Platforms.OrderBy(p=>p.PlatformID.ToList();
}
}
}
我被难住了。凯文,
哦,这有点复杂,迫使您返回EFv1模式,因为使用M:M时,您没有外键可依靠,并且您只能使用对象
添加游戏时,您确实希望添加关系(即连接表中的一行),但不希望添加平台,因为它只是一个引用
我还没有真正做到这一点,但我认为如果你能把它拆开,然后在游戏被连接并标记为添加后重建平台集合,这会更容易。否则,如果您添加整个图形,所有内容都会被标记为added
EF的问题是,如果你附加游戏,你也会附加相关的东西。可能会有一个更干净的模式,但我的想法是将平台从游戏中分离出来,将游戏附加到上下文中,将其标记为已添加。然后我会将平台附加到上下文。它们将“不变”。然后将它们添加到games.platform集合中。平台仍将保持不变,但:将被理解
你可能已经试过了。我必须自己去做,在我前进的过程中观察事物的实体状态,以确定发生了什么。关键是EF需要跟踪已添加的关系以及新的关系(并将导致添加联接表中的一行),但要了解平台不是新的
嗯
朱莉听起来不错,但我不确定如何将平台与游戏连接/分离。Intellisense没有给我任何提示。
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();
}
}
}