2017-02-01 5 views
0

大丈夫ですので、1つのフィールドを除いてほぼ同じである必要がある2つのテーブルを作成する必要があります。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プロパティは、ここではすべてのモデルの間で異なるので、私は、単一の(一般にすべてを統一する方法があるかもしれないと思いましたか? )クラス。

私はこれを実装するには2つの方法を考え出すことができます:

  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にします。 NHibernateがClassMap<>を作成するときobjectとしてdynamicプロパティを扱うので、どちらも機能しません。

この問題を解決する方法はありますか?

答えて

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(); 
} 
関連する問題