2016-12-28 2 views
0

NHibernate 맵핑만을 사용하여 여러 컬럼에 대한 참조를 작성할 생각이 있습니까? 이 매핑은 하나의 열만 허용합니다.다중 컬럼으로 구성된 기본 키에 코드로 NHibernate 마핑을 정의하십시오.

Bag(p => p.Childs, 
    map => 
    { 
     map.Key(k => 
      { 
       k.Column("KeyPart1"); 
      }); 
     map.Key(k => 
      { 
       k.Column("KeyPart2"); 
      }); 
    } 
    , ce => ce.OneToMany()); 

이 (XML 태그의 제거) 매핑 결과 :

<bag name="Childs"> 
    <key column="KeyPart1" /> 
    <one-to-many class="Child" /> 
</bag> 

이 오류가 발생합니다 결과 메시지 : NHibernate.FKUnmatchingColumnsException : 외래 키를 (FK1C5AAEC658BD05ED : 아이 [KeyPart2])

,785,872 :) 참조 기본 키 컬럼 (부모 [KeyPart1, KeyPart2])

아이 매핑된다 수가 같아야

는하지만 핵심 부품 모두, 나는이 매핑을 필요가 있다고 생각 :

<bag name="Childs"> 
    <key column="KeyPart1" /> 
    <key column="KeyPart2" /> 
    <one-to-many class="Child" /> 
</bag> 

이 클래스의 전체 구조입니다 : 당신이 (map.Key를 호출하기 때문에

public class ParentIdentifier 
{ 
    public virtual string KeyPart1 { get; set; } 
    public virtual string KeyPart2 { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) 
      return false; 
     var t = obj as ParentIdentifier; 
     if (t == null) 
      return false; 
     if (KeyPart1 == t.KeyPart1 && KeyPart2 == t.KeyPart2) 
      return true; 
     return false; 
    } 

    public override int GetHashCode() 
    { 
     return (KeyPart1 + "|" + KeyPart2).GetHashCode(); 
    } 

    public override string ToString() 
    { 
     return string.Format("KeyPart1 = {0}; KeyPart2 = {1}", KeyPart1, KeyPart2); 
    } 
} 


[Serializable] 
public class Parent 
{ 
    #region Primary key 

    public virtual ParentIdentifier Id { get; set; } 

    #endregion Primary key 

    public Parent() 
    { 
     Childs = new List<Child>(); 
    } 

    public virtual IList<Child> Childs { get; set; } 
} 

public class ParentMap : ClassMapping<Parent> 
{ 
    public ParentMap() 
    { 
     Table("Parent"); 

     ComponentAsId(
      x => x.Id, 
      caim => 
      { 
       caim.Property(x => x.KeyPart1, pm => 
        { 
         pm.Column("KeyPart1"); 
         pm.Length(20); 
        }); 
       caim.Property(x => x.KeyPart2, pm => 
        { 
         pm.Column("KeyPart2"); 
         pm.Length(64); 
        }); 
      }); 

     Bag(p => p.Childs, 
      map => 
      { 
       map.Key(k => 
        { 
         k.Column("KeyPart1"); 
        }); 
       map.Key(k => 
        { 
         k.Column("KeyPart2"); 
        }); 
      } 
      , ce => ce.OneToMany()); 
    } 
} 

[Serializable] 
public class Child 
{ 
    #region Primary key 

    public virtual int ChildId { get; set; } 

    #endregion Primary key 

    public virtual Parent Parent { get; set; } 
} 


public class ChildMap : ClassMapping<Child> 
{ 
    public ChildMap() 
    { 
     Table("Child"); 

     Id(p => p.ChildId, 
      map => 
       { 
        map.Generator(Generators.Assigned); 
        map.Column("ChildId"); 
       }); 

     ManyToOne(p => p.Parent, 
      map => map.Columns(
       col1 => 
       { 
        col1.Name("KeyPart1"); 
       }, 
       col2 => 
       { 
        col2.Name("KeyPart2"); 
       } 
       )); 
    } 
} 

답변

0

가 .. .) 두 번째, 두 번째는 첫 번째를 오버라이드합니다! 대신 다음으로 전화해야합니다.

map.Key(k => 
     { 
      k.Columns(
       c1 => c1.Name("c1"), 
       c2 => c2.Name("c2") /*as many as you want*/ 
      ); 
     });