2010-08-22 2 views
1

데이터 모델 주위에 머리를 감싸는 데 어려움을 겪고 있습니다. 방금 메모리에있는 객체가 있어야만 클래스를 선언하는 방법을 보여주기 시작하겠습니다.하나의 엔티티에서 동일한 엔티티에 대해 2 대 다 관계의 효과를 얻으려면 어떻게해야합니까?

@interface PlayerState { 

    NSSet /* of SavedDie */ *savedDice; 
    NSSet /* of SavedDie */ *immediateRolls; 

} 

@property (nonatomic, retain) NSSet *savedDice; 
@property (nonatomic, retain) NSSet *immediateRolls; 

@end; 

저는 같은 종류의 두 그룹을 가지고 있습니다. 그래서 Core Data에서 모델링 할 때 PlayerState에서 SavedDie 로의 2 대 다 관계가 있다고 생각했습니다.

역 관계를 정의하려고하면 문제가 발생합니다. 첫 번째로, 나는 왜 to-many 관계가 왜 반전되어야하는지 이해하지 못합니다. 역관계를 정의하지 않으면 일관성을 유지할 책임이 있음을 이해합니다.하지만 그렇게해도 문제가있는 것 같습니다.

어쨌든 소유자 코드 인 SavedDie에서 하나의 관계를 정의 할 수는 있지만 코드에서 액세스 할 필요는 없습니다. savedDice의 역 관계를 소유자로 정의 할 수 있습니다. 그런 다음 immediateRolls의 역 관계를 소유자로 정의하려고하면 savedDice의 역 관계로 설정을 해제합니다. 물론 savedDice와 immediateRolls 둘 다로 소유자의 역관계를 설정할 수는 없습니다.

답변

3

여기에서는 할 수없는 일을 할 수 없습니다. 내가 올바르게 당신을 이해한다면, 당신은 하나의 주인 관계를 갖기를 원하지만, playerState는 각각 두 명의 별개의 구원 받고 즉각적인 관계를 가지며, 각각은 주인에게 뒤로 링크됩니다. CoreData는 이것을 허용하지 않습니다.

아마도 모델을 약간 다시 생각해야합니다. 아마도 SavedDie 객체에 '저장된'롤인지 아니면 '즉각적인'롤인지 나타내는 플래그를 추가하십시오. 그런 다음 동적 속성을 추가하여 해당 플래그를 기반으로 저장된 또는 즉시 주사위를 가져옵니다. 각면에서 한 가지 관계. 물론, 더 잘 맞는다면 다른 방법이 있습니다.

2

위의 예제와 달리 코어 데이터는 관계 그래프를 유지 관리해야하기 때문에 코어 데이터에서 직접이 작업을 수행 할 수 없습니다.

이것을 이해하려면 위의 예제 코드를 사용하여 수동으로 관계를 설정한다고 가정하십시오. 이제 클래스가 savedDiceimmediateRollsPlayerState에 저장되어 있다고 가정 해 보겠습니다. 각 SavedDie 인스턴스가 PlayerState을 참조하도록하려면 소유하고있는 PlayerState에 대한 포인터를 만드는 것이 쉽지만 어떻게 저장된 PlayerState 속성인지 알 수 있습니다. 더 중요하게도 동일한 방법으로 동일한 SavedDie 개체를 실행하지 못하게 할 수 있습니다 두 속성 또는 두 개 이상의 개별 객체로 끝나지 않습니까? PlayerState?

코어 데이터는이 모든 것을 자동으로 관리하기 위해 생성되었으며 엔티티 그래프를 사용합니다. 엔티티는 클래스가 아닙니다. 대신 그들은 주로 개체간에 관계의 추상 표현입니다. 엔티티 그래프는 하나의 엔티티가 다른 엔티티와 두 개의 관계를 가지도록하지 않을 것입니다. 왜냐하면 라이브 데이터 오브젝트 중 어떤 인스턴스가 서로 연결되었는지 추적 할 수 없기 때문입니다.

두 가지 방법으로 문제를 해결할 수 있습니다.

(1) 엔티티 상속 사용 : Die 엔티티를 만들고 원하는 모든 특성으로 설정하십시오. 그런 다음 두 하위 사이트를 만듭니다. SavedDieImmediateDie.그럼 당신은 관계를 설정합니다

PlayerState.savedDie<-->SavedDie.playerState 
PlayerState.immediateDie<-->>ImmediateDie.playerState 

(2) 가져온 관계를 사용 :이 경우, 하나 Die 개체와 하나 개의 관계가 있습니다

PlayerState.Die<-->>Die.playerState 

을 ...하지만 당신이 Die의 속성을 가질 수 각 인스턴스를 저장 또는 즉시 작성합니다. 그런 다음 술어가 각각 플래그의 다른 상태를 찾는 두 개의 페치 관계를 작성합니다.

(3) 링크 개체를 사용하여이 기술에서, 당신과 같이 여러 관계에서 함께 두 가지 주요 요소를 묶어 중간 엔티티를 사용

PlayerState{ 
    //...some attributes 
    savedDice<-->>PlayerToSavedDie.playerState 
    immediateDice<-->>PlayerToImmediateDie.playerState 
} 

ToDie{ 
    die<-->SaveDie.player 
} 
PlayerToSavedDie:ToDie{ //...subentity of ToDie 
    //... no attributes 
    playerState<<-->PlayerState.savedDice 
} 

PlayerToImmediateDie:ToDie{ //...subentity of ToDie 
    //... no attributes 
    playerState<<-->PlayerState.savedDice 
} 

Die{ 
    player<-->ToDie.die 
} 

이 방법을 사용하면 주위에 Die 인스턴스를 이동할 수 있습니다 하나의 링크 관계를 삭제하고 다른 링크 관계를 만드는 것만으로도 관계를 유지할 수 있습니다. Die.playerToDie을 가리키고 있으므로 PlayerToSavedDie 또는 PlayerToImmediateDie을 해당 관계로 허용합니다.

이러한 기술 중 사용하는 방법은 데이터 모델의 필요에 따라 다릅니다. 한 관계의 논리적 Die 객체가 다른 관계로 절대 이동하지 않으면 (1)을 사용하십시오. 저장된 또는 즉각적인 데이터가 논리 Die 객체 자체의 중요한 속성 인 경우 (2)를 사용합니다. 논리적 Die 객체가 관계 사이를 이동하여 저장해야하거나 즉각적인 데이터가 논리적 Die 객체의 일부가 아닌 경우 (3)을 사용합니다.

것은이 모든 작업을 많이 보일 수도 있지만 하나 개의 수입 일을 기억해야한다 : 속성으로 관계 가져 오기로 단지입니다! 모델이 시뮬레이션 한 실제 개체, 이벤트 또는 조건을 관계가 반영하지 않으면 모델이 작동하지 않습니다. 관계에 대해 생각하고 관리하는 데 어느 정도 시간을 할애해야합니다.

코어 데이터를 사용하면 관계 관리가 100 배는 쉬워 지지만 여전히 작업이 필요합니다.

관련 문제