質問
Oracleデータベースがあり、フィールドの1つが日付範囲フィールドです。基本的には、YYYY / MM / DD-YYYY / MM / DD形式のVARCHAR(40)としてデータベースに保存されます。 nHibernateでこのように作成したカスタムクラスにマップしたい
public class DateTimeRange
{
public DateTimeRange(DateTime fromTime, DateTime toTime)
{
FromTime = fromTime;
ToTime = toTime;
}
public override string ToString()
{
return String.Format("{0} to {1}", FromTime.ToString("HH:mm:ss"), ToTime.ToString("HH:mm:ss"));
}
public DateTime FromTime { get; set; }
public DateTime ToTime { get; set; }
}
このようなカスタムクラスにマップするにはどうすればよいですか
解決
独自の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のインスタンスをロードし、カスタムマッピングタイプのプロパティを見つけると、カスタムタイプをロードし、NullSafeGetメソッドを呼び出します。ご覧のとおり、私のメソッドは返されたデータから名前を取得し、flyweightファクトリを呼び出してTypeClassの正しいインスタンスを取得し、実際にそのインスタンスを返します。型解決プロセスは、データアクセスクラス(およびNHibernate自体にも)に対して透過的に発生します。