2011-03-11 3 views
2

값에 고유 키 제약 조건을 포함하는 컴포넌트 목록을 매핑하려고합니다. (유형 간결하게 정돈 된)고유 키 제약 조건을 가진 컴포넌트리스트를 매핑하는 NHibernate

public class MyObject 
{ 
    public virtual int Id { get; set; } 
    public virtual IList<Alias> Aliases { get; set; } 
} 

public class Alias 
{ 
    public Alias(string type, string value) 
    { 
     Type = type; 
     Value = value; 
    } 

    public virtual string Type { get; protected set; } 
    public virtual string Value { get; protected set; } 
} 

그리고 MyObject를에서 관련 NHibernate에 매핑 :

<list cascade="all-delete-orphan" name="Aliases" table="MyObject_Aliases" mutable="true"> 
     <key> 
     <column name="MyObject_id" /> 
     </key> 
     <index> 
     <column name="`Index`" /> 
     </index> 
     <composite-element class="Alias"> 
     <property name="Type" type="System.String"> 
      <column name="Type" unique-key="UK_Alias" /> 
     </property> 
     <property name="Value" type="System.String"> 
      <column name="Value" unique-key="UK_Alias" /> 
     </property> 
     </composite-element> 
    </list> 

의도는 방지하는 것입니다

A는 '손질'클래스의 샘플은 다음과 같습니다 두 개의 MyObject가 동일한 별칭을 포함하지 않습니다.

이것은 MyObject에 새 별칭을 추가 할 때 완벽하게 작동합니다. 그러나 제거 된 별칭 다음에 별칭이있는 별칭을 목록에서 제거하려는 경우 NHibernate는 키 위반을 일으키는 목록을 재정렬하려고합니다.

자 NHibernate가 생성하는 SQL의 예입니다 :이 예에서는

-- statement #1, saving MyObject.Aliases 
INSERT INTO MyObject_Aliases 
      (MyObject_id, 
      "Index", 
      Type, 
      Value) 
VALUES  (101 /* @p0 */, 
      0 /* @p1 */, 
      'A' /* @p2 */, 
      'ALIAS1' /* @p3 */) 

INSERT INTO MyObject_Aliases 
      (MyObject_id, 
      "Index", 
      Type, 
      Value) 
VALUES  (101 /* @p0 */, 
      1 /* @p1 */, 
      'A' /* @p2 */, 
      'ALIAS2' /* @p3 */) 

-- statement #2, updating MyObject.Aliases after removing the first list item 
UPDATE MyObject_Aliases 
SET Type = 'A' /* @p0 */, 
     Value = 'ALIAS2' /* @p1 */ 
WHERE MyObject_id = 101 /* @p2 */ 
     AND "Index" = 0 /* @p3 */ 

문 # 2 예외 :

NHibernate.Exceptions.GenericADOException : could not update collection rows: [MyObject.Aliases#101][SQL: UPDATE MyObject_Aliases SET Type = ?, Value = ? WHERE MyObject_id = ? AND "Index" = ?] 
    ----> System.Data.SQLite.SQLiteException : Abort due to constraint violation 
columns Type, Value are not unique 

자체가 실제로 무슨 일이 일어나고 있는지에 따라 완벽한 의미가 예외, 하지만 예상대로 실제로 작동하도록하려면 어떻게해야합니까?

+1

목록 매핑을 사용해야합니까, 아니면 대신 세트를 사용할 수 있습니까? – Vadim

+0

내 자신의 무지와는 별도로 세트를 사용할 수없는 이유가없는 것 같아요. 실제로 큰 차이가 아닌 내 자신의 비교기를 구현해야 할 필요가 없으므로 실제로 작동하는 것처럼 보입니다. 만약 당신이 나를 위해 실제 답변으로 귀하의 의견을 돌리는 데 관심이 대답을 표시 할 수있는 능력이 질문 싶어요! –

+0

'list' 매핑 **이 필요한 경우 해결책은 무엇입니까? – MarioDS

답변

1

컬렉션을 인덱싱 할 필요가없는 경우 대신 집합 매핑을 사용해야합니다. 집합은 중복이 없음을 보장하는 컬렉션 유형입니다. 목록은 색인 할 수있는 콜렉션 유형입니다.

+0

인덱스를 사용하여 내 컬렉션에 액세스 할 수 없지만 LINQ와 관련하여 세트를 선별하는 것이 더 쉬워졌습니다. –

+0

@Chris, 당신은 여전히 ​​코드로 컬렉션을 색인 할 수 있습니다. 목록을 속성으로 표시하면, 좋은 예가 여기에 있습니다. http://stackoverflow.com/questions/824587/how-to-map-a-collectiont- in-nhibernate – Vadim

+0

이 질문과 똑같은 문제가 있지만 'list'매핑을 사용해야 할 필요가 있습니다. 이 문제를 어떻게 해결할 수 있습니까? – MarioDS

관련 문제