열망하는 로딩 데이터 퍼스의 페치 깊이를 어떻게 제어합니까?
-
05-07-2019 - |
문제
게으른 속성이없는 속성을 열망하는 Datamapper 클래스가 있습니다. 나는 주와 국가의 두 개체를 가지고 있으며, 국가는 국가와 국가와의 모든 주 목록이 포함되어 있다는 점에서 국가와 반비례 관계가 있습니다. 할당됩니다. 그러나이 개체 중 하나를 시도하고 검색하면 상태가 발생한다고 가정 해 봅시다.
- 상태는 Mapper에 의해로드됩니다
- Mapper는 열망하는 부동산 국가에 도달합니다
- Mapper는 그 주를 위해 국가를 회수합니다
- Mapper는 나라를로드합니다
- Mapper는 국가의 열렬한 수집 속성에 도달합니다
- Mapper는 상태 목록을로드하고 캐시를 사용하여 각 개인을 매핑하기 시작합니다.
- 국가에로드 된 각 주마다 1
이 루프를 피할 수있는 방법에 대해서는 상실합니다. 그래서 주로 아이디어를 찾고 있습니다. 누구나 요청하는 코드를 게시 할 것입니다. 그러나이 프로세스에는 많은 코드 줄이 포함되어있어 코드로 질문을 범람하고 싶지 않았습니다.
미리 감사드립니다!
편집하다:
Matt Howells의 조언을 따르고 DataMapper 패턴에 대해 더 깊이 조사한 후 Martin Fowler는 실제로 169 페이지와 170 페이지의 주기적 참조에 대해 이야기합니다. 그의 제안은 빈 개체를 사용하여 Identity Map에로드하여 재귀를 중지하는 것입니다. 로딩. 나는 지금이 단락을 지금 약 1000 번 읽었지만 여전히 이것이 부하를 어떻게 멈추는 지 이해하지 못한다. 그리고이 빈 객체를 언제 내 신분 맵에로드 해야하는지에 대해 또는 어떻게 알 수 있는지에 대해서는 잃어버린 것 이상의 것을 이해하지 못한다. 여기서 밀도가 높아서 사과 드리지만 이것은 내 머리 위로 날아가는 것 같습니다.
다시 한 번 감사드립니다.
해결책
로드 된 객체를 추적하는 저장소를 통해 객체를로드하는 것을 고려하십시오.
편집 : 자신의 ORM을하고 있다면 (그렇지 않은 경우에도) Enterprise Application Architecture의 Martin Fowler의 책 패턴을 적극 권장합니다. 나는 책 에서이 루프 상황에 대해 이야기하는 것을 모호하게 기억합니다. 그래서 도움이 될 수 있습니다.
편집 2 : 루프의 4 단계와 5 단계에서 이미 국가를로드 한 경우 이미로드되어야하므로 상태를 간절히로드 할 필요가 없습니다. 이것은 무한 루프를 깨뜨립니다.
다른 팁
Datamapper는 원형 참조를 포착해야합니다. 자체 재배 데이터 퍼스입니까?
나는 단지 내가 생각해 낸 솔루션을 게시하고 싶었지만이 고양이를 피부하는 방법이 많이 있다고 생각합니다.
다음은 제가 만든 FetchDepthCounterClass입니다.
public static class FetchDepthCounter
{
private static Dictionary<Type, int> _DepthCounter;
private static int _MaxDepth = 3;
static FetchDepthCounter()
{
_DepthCounter = new Dictionary<Type, int>();
}
public static void SetDepth(int depth)
{
_MaxDepth = depth;
}
public static void ResetCounter()
{
_DepthCounter.Clear();
}
public static bool IncrementCounter(Type entityType)
{
if(!_DepthCounter.ContainsKey(entityType))
{
_DepthCounter.Add(entityType, 0);
return true;
}
if(_DepthCounter[entityType] < _MaxDepth)
{
++_DepthCounter[entityType];
return true;
}
return false;
}
}
DecrementCounter는 Max Fetch 깊이에 도달했는지 여부를 진술하는 부울을 반환합니다. 부동산 값을 설정하기 직전에 매핑 프로세스의 일부로 증분 카운터를 호출합니다. 먼저 내가로드해야 할 것은 또 다른 DTO 객체 또는 DTO 모음이며 부모의 해당 유형의 유형 및 증분. 그래서 이것은 내 데이터 퍼스의 setValue 메소드 내부의 작은 코드입니다.
if(isDto)
{
if (!FetchDepthCounter.IncrementCounter(property.ComponentType))
return;
}
그것이 바로 그렇게하는 것 같습니다. 내 단위 테스트가 모두 통과됩니다. 모두의 도움에 감사드립니다. 나는 이것이 나중에 누군가를 도울 수 있기를 바랍니다. 다시 한 번, 이것은 아마도 작업 단위로 포장하는 것이 훨씬 쉬웠을 것입니다. 결국 그렇게 할 수도 있지만, 지금은 작업을 수행합니다.