edit #2: Question solved halfways. Look below
As a follow-up question, does anyone know of a non-intrusive way to solve what i’m trying to do below (namely, linking objects to each other without triggering infinite loops)?
I try to create a asp.net-mvc web application, and get a StackOverFlowException. A controller triggers the following command:
public ActionResult ShowCountry(int id) { Country country = _gameService.GetCountry(id); return View(country); }
The GameService handles it like this (WithCountryId is an extension):
public Country GetCountry(int id) { return _gameRepository.GetCountries().WithCountryId(id).SingleOrDefault(); }
The GameRepository handles it like this:
public IQueryable<Country> GetCountries() { var countries = from c in _db.Countries select new Country { Id = c.Id, Name = c.Name, ShortDescription = c.ShortDescription, FlagImage = c.FlagImage, Game = GetGames().Where(g => g.Id == c.GameId).SingleOrDefault(), SubRegion = GetSubRegions().Where(sr => sr.Id == c.SubRegionId).SingleOrDefault(), }; return countries; }
The GetGames() method causes the StackOverflowException:
public IQueryable<Game> GetGames() { var games = from g in _db.Games select new Game { Id = g.Id, Name = g.Name }; return games; }
My Business objects are different from the linq2sql classes, that’s why I fill them with a select new.
An unhandled exception of type ‘System.StackOverflowException’ occurred in mscorlib.dll
edit #1: I have found the culprit, it’s the following method, it triggers the GetCountries() method which in return triggers the GetSubRegions() again, ad nauseam:
public IQueryable<SubRegion> GetSubRegions() { return from sr in _db.SubRegions select new SubRegion { Id = sr.Id, Name = sr.Name, ShortDescription = sr.ShortDescription, Game = GetGames().Where(g => g.Id == sr.GameId).SingleOrDefault(), Region = GetRegions().Where(r => r.Id == sr.RegionId).SingleOrDefault(), Countries = new LazyList<Country>(GetCountries().Where(c => c.SubRegion.Id == sr.Id)) }; }
Might have to think of something else here 🙂 That’s what happens when you think in an OO mindset because of too much coffee
The problem might be this: countries have subregions and subregions have countries. I don’t know how you implement the lazy list, but that might keep calling GetCountries and then GetSubRegions and so on. To find that out, I would launch the debugger en set breakpoints on the GetCountries and GetSubRegions method headers.
I tried similar patterns with LinqToSql, but it’s hard to make bidirectional navigation work without affecting the performance to much. That’s one of the reasons I’m using NHibernate right now.