编辑#2:问题解决了一半。看下面
作为一个后续问题,有没有人知道一种非侵入性的方法来解决我在下面尝试做的事情(即,在不触发无限循环的情况下将对象链接到彼此)?
我尝试创建一个asp.net-mvc Web应用程序,并获得StackOverFlowException。控制器触发以下命令:
public ActionResult ShowCountry(int id)
{
Country country = _gameService.GetCountry(id);
return View(country);
}
GameService像这样处理它(WithCountryId是扩展名):
public Country GetCountry(int id)
{
return _gameRepository.GetCountries().WithCountryId(id).SingleOrDefault();
}
GameRepository像这样处理它:
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;
}
GetGames()方法导致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对象与linq2sql类不同,这就是我用select new填充它们的原因。
mscorlib.dll中出现未处理的“System.StackOverflowException”类型异常
编辑#1:我找到了罪魁祸首,它是以下方法,它会触发GetCountries()方法,该方法又会再次触发GetSubRegions(),令人作呕:
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))
};
}
可能必须在这里想到别的东西:)当你因为过多的咖啡而在OO心态中思考时会发生什么
答案 0 :(得分:2)
海!我认为你的模型是无意中递归调用一个方法,这会导致堆栈溢出。例如,您的Subregion对象正在尝试获取Country对象,而这些对象又必须获取Subregions。
无论如何,在StackOverflow异常中检查堆栈总是有帮助的。如果你看到一次又一次地访问一个属性,很可能是因为你正在做这样的事情:
公共对象MyProperty {set {MyProperty = value; }}
更容易发现像你这样的情况,方法A调用方法B调用方法A,因为你可以看到在调用堆栈中出现两次或多次相同的方法。
答案 1 :(得分:1)
问题可能是:国家有次区域,次区域有国家。我不知道你是如何实现惰性列表的,但是可能会继续调用GetCountries,然后调用GetSubRegions等等。为了找到它,我将在GetCountries和GetSubRegions方法头上启动调试器设置断点。
我尝试使用LinqToSql的类似模式,但很难在不影响性能的情况下进行双向导航。这就是我现在正在使用NHibernate的原因之一。
答案 2 :(得分:1)
回答您编辑过的问题,即:“将对象链接到彼此而不触发无限循环”:
假设你有某种关系,双方都需要了解另一方......掌握双方所有相关实体,然后将它们联系在一起,而不是试图取得一面自动获取另一个。或者只是让一个方获取另一个,然后修复剩下的一个。因此,在您的情况下,选项将是:
选项1:
选项2:
(或反向国家和次区域)
它们基本上是等式答案,只是在你进行某些链接时会发生变化。