编辑#2:问题中途解决。往下看
作为后续问题,有没有人知道一种非侵入式的方法来解决我在下面尝试做的事情(即,将对象相互链接而不触发无限循环)?
我尝试创建一个 asp.net-mvc web 应用程序,并得到一个 StackOverFlowException。 Controller 触发以下命令:
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;
}
我的业务对象与 linq2sql 类不同,这就是为什么我用一个新的选择来填充它们。
在 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 思维方式思考时会发生的事情
最佳答案
嗨!我认为您的模型无意中递归调用了一个方法,这会导致堆栈溢出。例如,您的 Subregion 对象正在尝试获取 Country 对象,而 Country 对象又必须获取 Subregions。
无论如何,在 StackOverflow 异常中检查堆栈总是有帮助的。如果您看到一个属性被一遍又一遍地访问,很可能是因为您正在做这样的事情:
公共(public)对象 MyProperty { 设置 { MyProperty = 值; }}
更容易发现像您这样的情况,其中方法 A 调用方法 B,方法 B 调用方法 A,因为您可以看到相同的方法在调用堆栈中出现两次或更多次。
关于asp.net-mvc - 由 linq 查询引起的 StackOverflowException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/238490/