문제

동일한 클래스의 다른 인스턴스에 클래스를 어떻게 매핑합니까? 그 관계에 속성 자체가있을 때?

테이블 사람에게 매핑되는 사람이라는 수업이 있습니다.

PersonID   PersonName    PersonAge 
----------------------------------
       1   Dave Dee             55
       2   Dozy                 52
       3   Beaky                45
       4   Mick                 55
       5   Tich                 58

나는 Personperson이라는 가입 테이블을 사용하는 사람과 사람 사이의 많은 관계를 원합니다.

 PersonPersonID  PersonID  RelatedPersonID RelationshipID 
 --------------------------------------------------------
              1         1                5              1
              2         3                4              2
              3         2                1              3

개인 테이블의 다음 속성을 원합니다.

RelationshipID  RelationshipName
--------------------------------
             1  Colleague
             2  Manager
             3  Tutor

이 질문 그리고 링크된다 Billy McCafferty의 게시물 사람의 관계는 개인 테이블의 추가 열이기 때문에 개인 관계를 정상적인 엔티티 자체로 홍보해야한다고 설명합니다. 그러나 자체 결합 일 때 무엇을 설명하지 않습니다. 차이점은 내가 모든 관련자들에게 요청하면 데이브 디 (ID = 1), 내가 얻어야 할뿐만 아니라 티쉬 (ID = 5), 그러나 나도 얻어야합니다 어리석은 (ID = 2) Dave Dee도 관련 인기 열에 있기 때문에 (ID = 2).

내 솔루션은 지금까지 내 개인 수업에 두 가지 속성을 갖는 것입니다.

public virtual IList<PersonPerson> PersonPersonForward {get;set;}
public virtual IList<PersonPerson> PersonPersonBack {get;set;}

private List<PersonPerson> personPersonAll;
public virtual List<PersonPerson> PersonPersonAll 
{
   get
   {
       personPersonAll = new List<PersonPerson>(PersonPersonForward);
       personPersonAll.AddRange(PersonPersonBack);
       return personPersonAll;
   }
}

그리고 HBM에서 다음과 같이하십시오.

 <bag name="PersonPersonForward" table="PersonPerson" cascade="all">
      <key column="PersonID"/>
      <one-to-many class="PersonPerson" />
 </bag>

 <bag name="PersonPersonBack" table="PersonPerson" cascade="all">
      <key column="RelatedPersonID"/>
      <one-to-many class="PersonPerson" />
 </bag>

이것은 사소하고 어리석은 것처럼 보입니다. nhibernate는 일반적으로 대부분의 일상적인 문제에 대한 우아한 솔루션을 가지고 있습니다. 위의 현명한 방법 이이 작업을 수행합니까, 아니면 더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

나는 그렇게 할 것이라고 생각하지만, 이런 식으로 모델링하는 것은 약간의 '서투른'것이라고 생각합니다. 내 말은 : 당신은 특정 사람이 관련된 사람을 가지고 있지만, 당신은 또한 '역 관계'도 있습니다.
이것이 정말로 필요합니까? 이 배출을 제거하고 대신 주어진 사람과 어떤 관계가있는 모든 사람을 되 찾을 수있는 개인의 양의 방법을 지정하는 옵션이 아닙니까?

흠, 이것은 약간 모호하게 들릴 수 있습니다. 여기에 일부 코드가 있습니다 (간결성을 위해서는 '가상'수정 자 등을 제외했습니다 ... (또한 수정자를 갖지 않는 것이 좋습니다. 시간의 %, 나는 클래스 맵핑에서 'Lazy = false'를 지정합니다).

public class Person
{
    public int Id {get; set;}
    public string Name {get; set;}

    public IList<PersonPerson> _relatedPersons;

    public ReadOnlyCollection<PersonPerson> RelatedPersons
    {
        get
        {
           // The RelatedPersons property is mapped with NHibernate, but
           // using its backed field _relatedPersons (can be done using the 
           // access attrib in the HBM.
           // I prefer to expose the collection itself as a readonlycollection
           // to the client, so that RelatedPersons have to be added through
           // the AddRelatedPerson method (and removed via a RemoveRelatedPerson method).

           return new List<PersonPerson) (_relatedPersons).AsReadOnly();
        }
    }

    public void AddRelatedPerson( Person p, RelationType relatesAs )
    {
       ...
    }

}

보시다시피, 사람 클래스에는 하나의 컬렉션 만 남았습니다. 즉,이 사람이 가진 관계를 나타내는 사람 대상의 모음입니다. 주어진 사람과 관계가있는 사람을 얻기 위해서는 개인 반복에 대한 특정 방법을 만들 수 있으며, 개인 수업에 컬렉션을 갖는 대신 해당 사람을 반환하는 데 도움이됩니다. 나는 이것이 성능을 향상시킬 것이라고 생각합니다.

public class NHPersonRepository : IPersonRepository
{
    ...

    public IList<Person> FindPersonsThatHaveARelationShipWithPerson( Person p )
    {
        ICriteria crit = _session.CreateCriteria <Person>();

        crit.AddAlias ("RelatedPersons", "r");

        crit.Add (Expression.Eq ("r.RelatedWithPerson", p));

        return crit.List();

    }
}

'역 참조'는 개인 수업의 구성원이 아닙니다. 저장소를 통해 액세스해야합니다. 이것은 또한 Eric Evans가 그의 DDD -Book에서 말하는 것입니다. 어떤 경우에는 저장소에 특수한 방법을 사용하여 관련 객체에 액세스 할 수있는 (= 관련 객체)를 가지고 다닐 수있는 것이 좋습니다. 객체 자체로.

나는 코드를 테스트하지 않았고 여기에 입력했기 때문에 구문 오류 등을 확인하지 않았지만 이것을 어떻게 볼 수 있는지에 대해 조금 명확히해야한다고 생각합니다.

다른 팁

당신이 본질적으로 모델을 만든 것처럼 보입니다. 지시 된 그래프, 두 개의 매핑 PersonPersonForward 그리고 PersonPersonBack 나가는 가장자리를 각각 나타냅니다.

이 지시는 관계 유형의 의미에 의해 강화됩니다. IS-A-COLEAGUE-OF 아마도 아마도 a 대칭 관계, IS-A-MANAGER-OF 그리고 is-a-tutor-of 거의 확실히 비대칭입니다.

이 경우 데이터 모델은 두 개의 링크 컬렉션이 호환되는 유형의 링크가 컨텍스트에서 동일하지 않다고 말하려고 노력하고 있다고 생각합니다.

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