2010-03-02 4 views
3

나는 NHibernate ICompositeUserType 매핑을 작동 시키려고했습니다. 그러나 다른 테이블에서 사용할 수 있도록 구현을 일반화하기 위해 노력하고 있습니다.다른 열 이름을 가진 다른 테이블에 ICompositeUserType 사용

레거시 데이터베이스에는 위도와 경도가있는 여러 테이블이 있으며 위치 클래스로 내 도메인 개체에 매핑하려고합니다. 문제는 각 테이블의 위도와 경도 열에 다른 이름이 있다는 것입니다.

ICompositeUserType 구현을 만들었지 만 속성 이름을 표의 열 이름으로 설정해야하는 것으로 보입니다. 즉 다른 표에서 다른 열 이름을 사용하여 CustomType을 사용할 수 없다는 의미입니다. .

나는 내 위치 클래스의 속성 이름에로 propertyNames를 설정하고 내 ClassMap의 테이블 컬럼에 매핑해야한다고 생각하지만, 이것은의 NHibernate에 예외를 던질 것 같다

NHibernate.MappingException: property mapping has wrong number of columns 

을 그것은 내가 매핑에서 뭔가 잘못하고있는 것처럼 느껴지지만, 나는 그것을 알아낼 수 없습니다.

public class PositionUserType : ICompositeUserType 
{ 
    private readonly IType[] _propertyTypes = 
    new [] { NHibernateUtil.Double , NHibernateUtil.Double }; 

    private readonly string[] _propertyNames = 
    new[] { "Latitude", "Longitude" }; 

    public string[] PropertyNames { get { return _propertyNames; } } 

    public IType[] PropertyTypes { get { return _propertyTypes; } } 

    // Other methods omitted 
} 

내 수업지도 :

public class LastPositionMap : ClassMap<LastPosition> 
{ 
    public LastPositionMap() 
    { 
     Map(p => p.Position) 
      .Columns.Add("LPLongitude", "LPLongitude") 
      .CustomType(typeof(PositionUserType)); 

     // Other mapping omitted 
    } 
} 

과 위치 클래스 I 현재이있어

public class Position 
{ 
    public double Latitude { get; private set; } 
    public double Longitude { get; private set; } 

    public Position(double latitude, double longitude) 
    { 
    Latitude = latitude; 
    Longitude = longitude; 
    } 
} 

여기

내 ICompositeUserType에서 코드의 조각이다 구성 요소가 유창한지도를 사용할 수있는 곳에서 작업하십시오. 그러나 이것은 Position 클래스가 변경 가능해야 함을 의미하며, 그렇지 않다면 그것을 얻으십시오.

아무도 도와 줄 수 있습니까? 여러 기사와 책을 잘 보았지만 여전히 작동하지는 않습니다.

public class LastPositionMap : ClassMap<LastPosition> 
{ 
    public LastPositionMap() 
    { 
     Map(p => p.Position) 

      // Clear the columns to get rid of Fluent NH's default column names 
      .Columns.Clear() 

      .ColumnsAdd("LPLongitude", "LPLongitude") 
      .CustomType(typeof(PositionUserType)); 

     // Other mapping omitted 
    } 
} 

당신이 추가하기 전에 열 컬렉션을 취소하지 않는 경우 :

감사합니다,

아담

+0

default(double)와 위치 클래스를 인스턴스화하는 것입니다. –

답변

4

당신은 당신의 매핑에 열 이름 재 지정을 추가하기 전에 열 컬렉션을 삭제해야 사용자 지정 이름 인 Fluent NH는 사용자 유형 매핑을 위해 새로운 열 이름을 열 컬렉션에 추가하기 만하므로 주어진 사용자 유형에 대해 너무 많은 열을 가져옵니다.

맵핑을 사용하여 유창한 맵핑에서 실제 XML 맵핑을 생성하는 경우.ExportTo() 귀하의 유창한 구성에서) 당신은 아마 같은 것을 볼 것이다 :

<property <!-- details here --> 
    <column name="Latitude" /> 
    <column name="Longitude" /> 
    <column name="LPLongitude" /> 
    <column name="LPLatitude" /> 
</property> 

가 실제로해야 할 때 :

<property <!-- details here --> 
    <column name="LPLatitude" /> 
    <column name="LPLongitude" /> 
</property> 
2

그것은 가변 될 필요가 없습니다, 당신은 개인을 사용할 수 있습니다 backingfield

Component(x => x.Position, c => 
    { 
     c.Map(p => p.Longitude, "LPLongitude").Access.BackingField(); 
     c.Map(p => p.Latitude, "LPLatitude").Access.BackingField(); 
    }) 

필요한 유일한 것은 usercode이

를 참조하지 않는 클래스에 매개 변수가없는 생성자입니다3210
protected Position() { } // to make NHibernate default implementation happy 

또 다른 가능성은 HBM 파일이 올바른 보이는 인스턴스 후크를 사용하여 생성자 당신이 도움이되지 않습니다 FNH와 매핑을 삭제, 게시와 같은 문제를 갖는

관련 문제