独自の IUserType を実装する必要があります。
詳細については、このブログ投稿を参照してください。また、ブログが消えた場合に備えて、関連するセクションを以下に貼り付けます。
NHibernate では、カスタム マッピング タイプは、IUserType または ICompositeUserType インターフェイスから派生するクラスです。これらのインターフェイスには、実装する必要があるいくつかのメソッドが含まれていますが、ここでの目的のために、そのうちの 2 つに焦点を当てます。以下を検討してください。
public class TypeClassUserType : IUserType
{
object IUserType.NullSafeGet(IDataReader rs,
string[] names,
object owner) {
string name = NHibernateUtil.String.NullSafeGet(rs,
names[0]) as string;
TypeClassFactory factory = new TypeClassFactory();
TypeClass typeobj = factory.GetTypeClass(name);
return typeobj;
}
void IUserType.NullSafeSet(IDbCommand cmd,
object value,
int index) {
string name = ((TypeClass)value).Name;
NHibernateUtil.String.NullSafeSet(cmd, name, index);
}
}
このクラスを作成したので、ActualClass と TypeClass の間の関連付けを、ActualClass マッピングの単純なプロパティとして明示的にマップできるようになりました。
<property
name="Type"
column="TypeName"
type="Samples.NHibernate.DataAccess.TypeClassUserType,
Samples.NHibernate.DataAccess" />
NHibernate は ActualType のインスタンスを保存する過程にあるため、TypeClassUserType の新しいインスタンスを読み込んで作成し、NullSafeSet メソッドを呼び出します。メソッド本体からわかるように、マップされたプロパティ (値パラメーターとして渡される) から名前を抽出し、抽出された名前をデータベースに設定するパラメーターの値として設定するだけです。最終的な結果として、ドメイン モデルでは ActualClass の Type プロパティは TypeClass ですが、TypeClass オブジェクトの Name プロパティのみがデータベースに格納されます。逆も真です。NHibernate がデータベースから ActualType のインスタンスをロードしているときに、カスタム マッピング タイプのプロパティが見つかると、NHibernate はカスタム タイプをロードして NullSafeGet メソッドを呼び出します。ご覧のとおり、私のメソッドは返されたデータから名前を取得します。Flyweight ファクトリを呼び出して TypeClass の正しいインスタンスを取得し、実際にそのインスタンスを返します。型解決プロセスは、データ アクセス クラスに対して透過的に行われます (さらに言えば、NHibernate 自体に対しても)。