20

관계의 양측이 같은 엔티티를 참조하는 다 대다 관계를 맵핑하는 데 문제점이 있습니다. Fluent NHibernate와 NH3.1을 사용하고 있습니다.유창한 nhibernate - 동일한 엔티티에 대한 다 대다 관계 매핑

기본적으로 시나리오는 - 여러 개의 부모를 가질 수있는 카테고리가 있습니다. 따라서 카테고리에는 부모로 여러 개의 다른 카테고리뿐만 아니라 그 자녀로 여러 다른 카테고리가 있습니다. 내가 공장을 빌드 할 때

HasManyToMany(x => x.ParentCategories).AsBag().Table("parentcategorychildren").ParentKeyColumn("ChildID").ChildKeyColumn("ParentID").Cascade.SaveUpdate(); 
HasManyToMany(x => x.ChildrenCategories).AsBag().Table("parentcategorychildren").ParentKeyColumn("ParentID").ChildKeyColumn("ChildID").Inverse(); 

그러나, 나는 다음과 같은 오류가 발생합니다 :

왜 Category.ChildrenCategories에 'Category.ChildrenCategories'을 언급이다 내가 이상한 발견하고

The relationship Category.ChildrenCategories to Category.ChildrenCategories has Inverse specified on both sides. Remove Inverse from one side of the relationship.

, ParentCategories와 반대로?

도움이 될 것입니다.

나에게 충분히 중요하기 때문에 방금이 현상금을 만들었습니다. 제발, 나는 대답 할 수 없다는 것에 관심이 없습니다.

+0

우리는 똑같은 문제를 겪고 있습니다. 대답은 크게 감사하겠습니다. –

+0

FNH의 버그 일 경우 항상 전통적인 xml 매핑이나 답변에 제공된 해결 방법을 사용할 수 있습니다. – Vadim

+0

나는 이것을 위해 [문제] (http://fluentnhibernate.lighthouseapp.com/projects/33236-fnh/tickets/212-inverse-validation-fails-on-self-referential-relationships)를 제기했다. 우리는 최대한 빨리 해결할 것입니다. –

답변

12

이것은 FNH 버그 일 가능성이 높으며 가장 최근 FNH source code에서 이미 수정되었을 가능성이 큽니다. FNH1.0과 NH2.1을 사용할 때 아무런 문제가 없습니다. 등가 HBM 매핑은 FNH1.2 및 NH3.1에서 잘 작동합니다

<bag name="ParentCategories" cascade="all" table="parentcategorychildren"> 
    <key column="ChildID" /> 
    <many-to-many column="ParentID" class="Category" /> 
</bag> 

<bag name="ChildrenCategories" inverse="true" table="parentcategorychildren"> 
    <key column="ParentID" /> 
    <many-to-many column="ChildID" class="Category" /> 
</bag> 

편집 : FNH 소스 코드에 파고 후 나는 해결 방법을 발견했다. 구성은 다음과 같다, 이제 가정 해 봅시다 :

.Mappings(m => { 
    m.FluentMappings.AddFromAssemblyOf<Category>(); 
}) 

불운 코드가 이러한 구성에 의해 억제 될 수 있습니다

.Mappings(m => { 
    var persistenceModel = new PersistenceModel(); 
    persistenceModel.AddMappingsFromAssembly(typeof(Category).Assembly); 
    persistenceModel.ValidationEnabled = false; // this makes the trick 
    m.UsePersistenceModel(persistenceModel); 
}) 
+0

체크 코드는 https://github.com/jagregory/fluent-nhibernate/blob/release-1.2/src/FluentNHibernate/Visitors/ValidationVisitor.cs에서 볼 수 있으며 여전히 최신 버전의 FNH 인 것으로 보입니다. 단일 맵에서만 유효성 검사를 비활성화하는 방법이 있습니까? –

+0

예, 1.2 태그입니다. 최신 코드는 마스터 브랜치 (https://github.com/jagregory/fluent-nhibernate/blob/master/src/FluentNHibernate/Visitors/ValidationVisitor.cs)에 있지만 마스터 브랜치에서 버전을 테스트하지 않았으므로 이미 그것이 맞는지 확실하지 않습니다 (단지 추측). 단일 MapClass에 대한 유효성 검사를 비활성화하는 방법을 모르지만 두 가지 유효성 검사 만 있습니다. 불필요한 것이고 Id가 매핑되어 있는지 확인하십시오. 나는 둘 다없이 happlyly 살 것이다 :). –

+0

무슨 일이 있었는지 오해 할 수는 있지만 마스터 브랜치가 구식 인 것처럼 보입니다. 2.1에있는 커밋이 누락되었습니다. 어떤 지점에서든이 문제에 대한 수정 사항을 볼 수 없습니다. –

6

이 관계의 유창함 NHibernate에 2.1의 검증/페어링에 문제가 있습니다. FNH pairs up relationships 다음에 validates that only one side of the relationship has .Inverse() specified. 두 참조 (부모/자식)가 같은 클래스에 속하기 때문에 쌍을 이루었을 때 두 후보가 모두 일치합니다. 이 경우 FNH matches on name similarity. 결과적으로, 그들은 서로보다는 오히려 그들 자신과 쌍을 이룹니다. 따라서 어느 한쪽에 .Inverse()을 배치하면 유효성 검사가 시작됩니다 (쌍의 양쪽이 반대 인 동일한 관계 임).

FluentMappingsContainer에서 OverrideBiDirectionalManyToManyPairing() 메서드를 사용하여이를 수정할 수 있어야합니다. 이론적으로, 그것은 당신이 명시 적으로 아이와 부모 관계를 쌍으로 만들 수 있습니다. 그러나 FNH 2.1에는 버그가있어 오버라이드 콜백이 호출되지 않습니다. (The callback value is captured before it can be set by the method).

해결 방법으로 FNH에서 모든 유효성 검사를 비활성화 할 수 있습니다. only two validations이 있습니다. 첫째, 관계의 양측에는 .Inverse()이 없습니다. 둘째, 각 엔티티에 ID가 매핑됩니다. 내가 검증을 중지하기로 한 가장 깨끗한 방법은 다음과 같습니다

.Mappings(m => { 
    var persistenceModel = new PersistenceModel() { ValidationEnabled = false }; 
    m.UsePersistenceModel(persistenceModel) 
    .FluentMappings.AddFromAssemblyOf<Category>(); 
}) 

이 방법을 사용하면 유효성 검사를 비활성화 할 수 있습니다 여전히 FluentMappings 구성의 전체 표현을 사용합니다.

+0

네,하지만 다른 오류도 억제 될 것입니다. 이는 주목할 필요없이 클래스 매핑의 향후 변경 사항에 문제가 있음을 증명할 수 있습니다. –

+0

잘 찾아 냈습니다! 나는 (분명히)이 시나리오를 고려하지 않았다. 나는 이것을 위해 [문제] (http://fluentnhibernate.lighthouseapp.com/projects/33236-fnh/tickets/212-inverse-validation-fails-on-self-referential-relationships)를 만들었으며 우리는 그것은 순식간에 정리했다. –

+0

Karl, 예, 유효성 검사를 비활성화하면 답안에서 철자하는 두 가지 검사가 비활성화됩니다. 더 많은 검증이 추가되면 문제가 될 수 있습니다. 그러나 Jakub의 답변은 약간 다른 코드를 사용하여 동일한 유효성 검사 집합을 비활성화하는 것입니다. –

0

네, Fluent NH를 사용하지 않고 NHibernate를 직접 사용해 보았을 때 FNH의 버그 일 가능성이 높았습니다.그러나 FNH를 사용하여 시스템을 설정 했으므로 사용하지 않는 것으로 되돌릴 수는 없습니다.

내가 한 것은 일반적으로 자동 생성되는 다 대다 관계에 대해 '클래스 속의 인물'처럼 만들었습니다. ParentsChildren 카테고리를 연결하는 ContentPage_ChildLink 페이지를 만들었습니다. 이것은 내가 FNH와 함께 작업하고 문제를 해결할 수있게 해줬습니다.

기본적으로이 ContentPage_ChildLinkChildIDParentID의 두 필드가 있습니다. 그런 다음 아무런 문제없이 '반전'관계를 별도로 설정할 수있었습니다.

FNH의 문제는 양면이 같은 클래스 인 다 대다 관계가있는 것처럼 보였습니다. 생각할 수있는 유일한 경우는 여러 부모를 허용하는 계층 구조입니다.

+0

우리가 가진 상황은 일부 계좌가 폐쇄되고 돈이 다른 계좌로 이전되는 은행 계좌입니다. 이렇게하면 계정마다 다 대다가 생성됩니다. –

+0

버그를 해결하기 위해 은행 계좌를 연결하는 또 다른 클래스를 만들어야합니다. 'MainAccountID'와'LinkedAccountID' 클래스를 가진'AccountLink' 클래스를 가질 수 있습니다. AccountLink는 일대 다 관계 'AccountLink' 테이블을 가진 일대 다 컬렉션 인'LinkedAccounts '를 가지고 있습니다. MainAccount.LinkedAccounts [0] .LinkedAccount를 수행하여 관계를 탐색 할 수 있습니다. 희망이 도움이됩니다! –