2010-02-09 3 views
2

POINT 유형의 두 가지 속성을 포함하는 클래스 LINE이 있습니다. POINT를 구성 요소 속성으로하고 싶습니다. LINE에 POINT가 1 개만 포함되어 있으면 문제가되지 않지만 POINT가 2 개이므로 구별 할 필요가 있다고 생각합니다. 따라서 접두어 나 접미어를 열 이름에 적용 할 수 있습니다. ComponentProperty 태그의 PropertyName 특성을 사용했지만 X 및 Y 열 집합 하나만 내 LINE 테이블 내에 생성되었습니다.클래스의 동일한 유형의 Nhibernate 다중 구성 요소 속성

명확성을 위해 저의 목표는 Point1_X, Point1_Y, Point2_X 및 Point2_Y 열이있는 LINE 테이블을 갖는 것입니다.

당신은 내가 알아 낸 한편 내 매핑

[Class] 
public class Line : EntityBase 
{ 
    [ComponentProperty(PropertyName = "Point1")] 
    public UiPoint Point1 { get; set; } 

    [ComponentProperty(PropertyName = "Point2")] 
    public UiPoint Point2 { get; set; } 

    //omitted the constructor 

}

[Component] 
public class UiPoint 
{ 
    [Property] 
    public double X { get; set; } 

    [Property] 
    public double Y { get; set; } 

    //omitted the constructor 
} 

을 볼 수 아래 나는 다음과 같은 XML 매핑 내 문제 해결 줘야 해, Nhibernate.Mapping.Attributes를 사용

<class name="Domain.WashProcessLine,Domain"> 
    <id name="Id" /> 
    <component name="Point1"> 
     <property name="X" type="Double" column="Point1_X" /> 
     <property name="Y" type="Double" column="Point1_Y" /> 
    </component> 
    <component name="Point2"> 
     <property name="X" type="Double" column="Point2_X" /> 
     <property name="Y" type="Double" column="Point2_Y" /> 
    </component> 
</class> 

에 대한 옵션이 발견되었습니다. https://www.hibernate.org/hib_docs/nhibernate/html/components.html

다음 태그를 지정하면 원하는 테이블 구조가 만들어 지지만 데이터베이스에서 속성을 가져올 때 캐스팅 예외 (UiPoint에서 IDictionary로)가 발생합니다. 그래서

나는 완전히이 아직 아니에요 :(

[Class] 
public class Line : EntityBase 
{ 
    [DynamicComponent(1)]    
    [Property(2, Name = "X", Column = "Point1_X", TypeType = typeof(double))] 
    [Property(3, Name = "Y", Column = "Point1_Y", TypeType = typeof(double))] 
    public UiPoint Point1 { get; set; } 

    [DataMember] 
    [DynamicComponent(1)]    
    [Property(2, Name = "X", Column = "Point2_X", TypeType = typeof(double))] 
    [Property(3, Name = "Y", Column = "Point2_Y",TypeType=typeof(double))] 
    public UiPoint Point2 { get; set; } 
} 

답변

1

Nhibernate.Mapping.Attributes에 대한 단위 테스트를보고, 다른 솔루션의 숫자를 시도 후, 우리가 발견 가장 깨끗한 방법 (불행하게도) 우리의 매핑에 일부 원시 XML을 주입했다 위에 제공된 상황을 해결합니다. 이것은 우리가 속성이 우리의 라인 클래스에 속성을 제거하고 단일 항목으로 그들을 대체 의미

[RawXml(After=typeof(ComponentAttribute), Content = @"<component name=""Point1""> 
<property name=""X"" type=""Double"" column=""Point1_X"" /> 
    <property name=""Y"" type=""Double"" column=""Point1_Y"" /> 
</component> 
<component name=""Point2""> 
    <property name=""X"" type=""Double"" column=""Point2_X"" /> 
    <property name=""Y"" type=""Double"" column=""Point2_Y"" /> 
</component>")] 
0

이 질문에 답변을 아래와 같이 wi 주위에 놀고있는 동안 나를 도왔다. th NHibernatePets Sample

나는 위의 라인/포인트 구현을 포함하도록하겠습니다. 누군가가 관심이 있다면 내 코드가 아래에 있습니다. 나는 Attributes를 사용하면서 좌절스러운 단점을 발견했다. 당신과 같은 [ID] 선언으로 여러 클래스를 사용하는 경우 것이되는 첫 번째 :

[Id(Name = "id")] 
    [Generator(1, Class = "native")] 

는 당신은 주문 번호를 (1) 발전기 또는 다른 생성 된 매핑에 대한 생성기 속성을 생략 할 수 있습니다 지정해야 하나 이상의 수업. 분명히 이것은 VS가 일을 처리하는 방식과 관련이 있습니다.

사용하여 생성 된 파일 출력 샘플 Pet.hbm.xml 파일을 비교할 때 내가 찾은 또 다른 한가지 :

//Export to a mapping file when required. Test/Production. HbmSerializer.Default.Serialize(typeof(Pet).Assembly,"Pets.hbm.xml");

가 액세스 = "필드가"속성이 설정되어서는 안된다는이었다 [ID] 특성 (샘플 매핑 파일에 있음에도 불구하고).

(NHibernatePets 네임 스페이스의) 라인 및 UiPoint 클래스 ...홈페이지()에서

[Class(Lazy = true)] 
public class Line 
{ 

    [Id(Name = "id")] 
    [Generator(1, Class = "native")] 
    #if useAttributes 
     virtual public int id { get; set; } 
    #else 
     private int id; 
    #endif 

    const string point1 = 
    @"<component name= ""Point1"" class= ""NHibernatePets.UiPoint"" > 
     <property name=""X"" 
       type=""Double"" 
       column=""Point1_X""/> 
     <property name=""Y"" 
       type=""Double"" 
       column=""Point1_Y""/> 
     </component>"; 

    const string point2 = 
    @"<component name=""Point2"" class=""NHibernatePets.UiPoint"" > 
      <property name=""X"" 
       type=""Double"" 
       column=""Point2_X""/> 
      <property name=""Y"" 
       type=""Double"" 
       column=""Point2_Y""/> 
     </component>"; 

    [RawXml(After = typeof(ComponentAttribute), Content = point1)] 
    virtual public UiPoint Point1 { get; set; } 

    [RawXml(After = typeof(ComponentAttribute), Content = point2)] 
    virtual public UiPoint Point2 { get; set; } 

} 

//Don't need any Attributes set on this class as it's defined in the RawXml. 
public class UiPoint 
{ 
    public double X { get; set; } 
    public double Y { get; set; } 
} 

... 공공 클래스 프로그램에서

 //Create the Line record 
     Line newLine = new Line 
     { 
      Point1 = new UiPoint { X = 100.1, Y = 100.2 }, 
      Point2 = new UiPoint { X = 200.1, Y = 200.2 } 
     }; 
     try 
     { 
      using (ISession session = OpenSession()) 
      { 
       using (ITransaction transaction = session.BeginTransaction()) 
       { 
        session.Save(newLine); 
        transaction.Commit(); 
       } 
       Console.WriteLine("Saved NewLine to the database"); 
      } 
     } 
     catch (Exception e) 
     { Console.WriteLine(e); } 

...

static ISessionFactory SessionFactory; 
    static ISession OpenSession() 
    { 

     if (SessionFactory == null) //not threadsafe 
     { //SessionFactories are expensive, create only once 
      Configuration configuration = new Configuration(); 

      #if useAttributes 
      { 
       configuration.SetDefaultAssembly("NHibernatePets"); 
       //configuration.SetDefaultAssembly(System.Reflection.Assembly.GetExecutingAssembly().ToString()); 
       //To use Components and other structures, AssemblyName must be set. 
       //configuration.SetDefaultAssembly(typeof(Pet).Assembly.ToString()); 
       configuration.AddInputStream(NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize(typeof(Pet).Assembly)); 
      } 
      #else 
       configuration.AddAssembly(Assembly.GetCallingAssembly()); 
      #endif 

      //Export to a mapping file when required. Test/Production. 
      HbmSerializer.Default.Serialize(typeof(Pet).Assembly,"Pets.hbm.xml"); 

      SessionFactory = configuration.BuildSessionFactory(); 
     } 
     return SessionFactory.OpenSession(); 
    } 
관련 문제