2011년 10월 12일 수요일

FluentNHibernate 으로 ManyToMany 매핑하기

HBM으로 매핑하는 것은 많은 예제가 있는데, FluentNHibernate으로 매핑하는 예제는 FluentNHibernate 사이트에 달랑 한 줄의 코드로 설명이 끝납니다.
아니 ManyToMany가 얼마나 복잡한 건데 달랑 한 줄에 끝내는 겨? 특히나 양방향 (bi-directional) 인 경우에는 둘 중 한 군데에 inverse=true 를 줘야 하는데, 그런 예도 없고 말야…
어쩔 수 없이 테스트를 해봤습니다… 우선은 상세한 매핑 설정을 통해 제대로 작동하는지 검증해 봤습니다.

Many-To-Many 상세 설정
   1: public class FDepartmentMap : ClassMap<FDepartment>
   2: {
   3:     public FDepartmentMap()
   4:     {
   5:         Table("FDepartment");
   6:         DynamicInsert();
   7:         DynamicUpdate();
   8:  
   9:         Id(x => x.Id).Column("DepartmentId").GeneratedBy.Native();
  10:  
  11:         Map(x => x.Code);
  12:         Map(x => x.Name);
  13:  
  14:         References(x => x.Parent)
  15:             .Column("ParentId")
  16:             .Access.Property()
  17:             .Cascade.SaveUpdate()
  18:             .Fetch.Select()
  19:             .LazyLoad(Laziness.Proxy);
  20:  
  21:         HasMany(x => x.Children)
  22:             .Access.CamelCaseField(Prefix.Underscore)
  23:             .Cascade.AllDeleteOrphan()
  24:             .Inverse()
  25:             .LazyLoad()
  26:             .AsSet(SortType.Natural);
  27:  
  28:  
  29:         Component<TreeNodePosition>(x => x.NodePosition,
  30:                                     p =>
  31:                                     {
  32:                                         p.Map(x => x.Order).Column("TreeOrder");
  33:                                         p.Map(x => x.Level).Column("TreeLevel");
  34:                                     });
  35:  
  36:         HasManyToMany(x => x.Users)
  37:             .Table("FDepartmentMember")
  38:             .ParentKeyColumn("DepartmentId")
  39:             .ChildKeyColumn("UserId")
  40:             .Inverse()
  41:             .LazyLoad()
  42:             .AsSet();
  43:     }
  44: }



보시다시피 many-to-many  매핑을 수행하는 부분은 소속 부서원들과의 매핑이고, 겸직을 고려한 설계입니다.

관계 table 명은 “FDepartmentMember” 이고, DepartmentId, UserId 의 값 설정으로 됩니다. 그리고, 중복을 방지하기 위해 ISet<FUser> 이구요…



이 방법은 제가 그 동안 HBM으로 매핑하는 방식에 익숙해서 모두 설정해 준 것이고, 실제로 다음과 같이만 해줘도




   1: HasManyToMany(x => x.Users)
   2:     .Table("FDepartmentMember")
   3:     .Inverse()
   4:     .AsSet();

똑 같은 결과를 얻는다는 것입니다.



FluentNHibernate의 AutoMapping 기능이 상당히 막강하여, 왠만한 정보는 Entity 클래스로부터 추출해 내므로, 굳이 매핑 시 지정하지 않아도 된다는 점입니다.

보면 볼 수록 FluentNHibernate은 매력적인 놈이라 생각됩니다.

댓글 없음: