2017-02-01 6 views
0

좋아, 그래서 하나의 필드를 제외하고는 거의 동일해야하는 두개의 테이블을 생성해야한다.NHibernate - 런타임 정의 타입의 프로퍼티를 매핑

class HouseGeometryModel 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    //More fields... 

    public virtual HouseAttributes Attributes { get; set; } 
} 

class DungeonGeometryModel 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    //More fields, all identical to HouseGeometryModel... 

    public virtual DungeonAttributes Attributes { get; set; } 
} 

class FortressGeometryModel 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    //More fields, all identical to HouseGeometryModel... 

    public virtual FortressAttributes Attributes { get; set; } 
} 

//More models... 

그래서, 기본적으로 단지 Attributes 속성이 여기에 모든 모델 사이의 차이, 그래서 하나의 (일반적으로 모든 것을 통합 할 수있는 방법이있을 수 있다고 생각 :

내 모델은 대략 다음과 같을까요?) 수업.

나는이를 구현하는 두 가지 방법을 마련 할 수 :

  1. 이 확인 같을 것이다 제네릭 클래스 GeometryModel<TAttributes> :

    class GeometryModel<TAttributes> 
    { 
        public virtual int Id { get; set; } 
        public virtual string Name { get; set; } 
        //More fields... 
    
        public virtual TAttributes Attributes { get; set; } 
    } 
    

    이 문제는 내가를 지정하지 않을 것입니다 유창한 매핑. 맵핑은 또한 (ClassMap<GeometryModel<TAttributes>>을 구현하기 위해)이 방식으로 일반화되어야하므로 NHibernate로 인스턴스화하는 것이 불가능할 것이다.

  2. Attributes 속성을 dynamic으로 지정하십시오. Hibernate가 속성을 ClassMap<>을 만들 때 object으로 처리하기 때문에 그것은 작동하지 않습니다.

어떤 해결책이 있습니까?

답변

0

런타임을 사용하여 일반적인 방법으로 수행했습니다. ClassMap<> 바인딩.

내 모델은 다음과 같습니다

class GeometryModel<TAttributes> 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    //More fields... 

    public virtual TAttributes Attributes { get; set; } 
} 

내 매핑

는 다음과 같이 :

class GeometryModelMap<TAttributes> : ClassMap<GeometryModel<TAttributes>> 
{ 
    public GeometryModelMap() 
    { 
     Id(t => t.Id).GeneratedBy.Increment(); 
     Map(t => t.Name); 
     //More mappings... 
     References(t => t.Attributes); 
    } 
} 

나는 다음과 같은 확장 방법을 썼습니다 :

private static FluentMappingsContainer AddGenericMappings(this FluentMappingsContainer container, Type genericType, IEnumerable<Type> genericArgs) 
{ 
    foreach (var arg in genericArgs) 
    { 
     var newType = genericType.MakeGenericType(arg); 
     container.Add(newType); 
    } 
    return container; 
} 

을 그리고는 다음과 같이 사용 :

private static ISessionFactory CreateSessionFactory(string path) 
{ 
    return Fluently.Configure() 
        .Database(SQLiteConfiguration.Standard.UsingFile(path)) 
        .Mappings(m => m.FluentMappings 
        .AddFromAssembly(Assembly.GetExecutingAssembly()) 
        .AddGenericMappings(typeof(GeometryModelMap<>), new[] { typeof(HouseAttributes), typeof(DungeonAttributes), typeof(FortressAttributes) } ) 
      ) 
      .ExposeConfiguration(config => BuildSchema(config, path)) 
      .BuildSessionFactory(); 
}