문제

#2 편집 : 질문은 반쯤 해결되었습니다. 아래를 봐

후속 질문으로, 누구든지 내가 아래에서하려는 일 (즉, 무한 루프를 트리거하지 않고 객체를 서로 연결하는 것을 해결하기위한 비 침입 방법을 알고 있습니까?


ASP.NET-MVC 웹 응용 프로그램을 만들고 stackoverFlowException을 얻으려고합니다. 컨트롤러는 다음 명령을 트리거합니다.

    public ActionResult ShowCountry(int id)
    {
        Country country = _gameService.GetCountry(id);
        return View(country);
    }

gameservice는 다음과 같이 처리합니다 (WithountryId는 확장입니다).

    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 사고 방식으로 생각할 때 일어나는 일입니다.

도움이 되었습니까?

해결책

문제는 다음과 같습니다. 국가에는 하위 지역과 하위 지역에 국가가 있습니다. 나는 당신이 게으른 목록을 어떻게 구현하는지 모르겠지만, 그것은 계속해서 GetCountries를 호출 한 다음 GetSubgregions 등을 호출 할 수 있습니다. 이를 알아 내기 위해 GetCountries 및 GetSubregions 메소드 헤더에서 디버거 세트 브레이크 포인트를 시작합니다.

LinqToSQL과 비슷한 패턴을 시도했지만 성능에 큰 영향을 미치지 않고 양방향 내비게이션 작업을 만드는 것은 어렵습니다. 그것이 제가 지금 nhibernate를 사용하는 이유 중 하나입니다.

다른 팁

하이! 귀하의 모델이 의도하지 않게 메소드를 재귀 적으로 호출하고 있다고 생각하여 스택 오버플로가 발생합니다. 예를 들어, 하위 지역 객체는 국가 대상을 얻으려고 노력하고 있으며, 이는 하위 지역을 가져와야합니다.

어쨌든, 그것은 항상 Stackoverflow 예외에서 스택을 확인하는 데 도움이됩니다. 속성에 계속해서 액세스하는 것을 보면 다음과 같은 일을하고 있기 때문에 가능성이 높습니다.

public object myProperty {set {myProperty = value; }}

통화 스택에서 두 번 이상 표시되는 동일한 메소드를 볼 수 있기 때문에 메소드 A가 메소드 A를 호출하는 메소드 B가 메소드 B를 호출하는 방법 B와 같은 상황을 발견하기가 더 쉽습니다.

편집 된 질문에 답하기 위해 : "무한 루프를 트리거하지 않고 객체를 서로 연결":

양측이 다른 사람에 대해 알아야 할 관계가 있다고 가정하면 ... 한쪽의 페치를 자동으로 가져 오려고 시도하는 대신 양측에 대해 알아야 할 관계가 있다고 가정합니다. 다른. 아니면 그냥 만들어 하나 측면은 다른 하나를 가져온 다음 나머지를 고치십시오. 따라서 귀하의 경우 옵션은 다음과 같습니다.

옵션 1:

  • 모든 국가 가져 오기 (하위 지역을 비워 두다)
  • 모든 하위 지역 가져 오기 (국가를 비워 두는)
  • 각 하위 지역에 대해 국가 목록을 살펴보고 하위 지역을 국가와 국가에 추가하여 하위 지역에 추가하십시오.

Option 2:

  • 모든 국가 가져 오기 (하위 지역을 비워 두다)
  • 위에 가져온 국가 목록을 통한 하위 지역을 설정하는 모든 하위 지역을 가져 오십시오.
  • 각 하위 지역에 대해 모든 국가를 통과하여 해당 국가에 추가하십시오.

(또는 역 국가 및 하위 지역)

그것들은 기본적으로 동등한 답변이며 링크를 수행 할 때만 변경됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top