としてカスタム型を使用して - 他の列のそのMD5ハッシュ。 NHibernateは、Equalsを実装していないので、キーとしてbyte []を扱えないので、これをカスタム型でラップし、NHibernateにIUserTypeの実装を提供しました。 MD5Hashはクラスではなく構造体であることに注意してください。NHibernateは:私は、バイナリ型(16)の主キーを持つテーブルが含まれているレガシースキーマを持っている主キー
public struct MD5Hash : IComparable, IComparable<MD5Hash>, IEquatable<MD5Hash> {
private readonly byte[] contents;
...
}
MD5Hashをキーとして多対1のマッピングを作成するまでは、すべてうまくいきました。
public class Referenced : IEquatable<Referenced> {
...
public virtual MD5Hash Id { get; set; }
public virtual string Name { get; set; } // must NOT be null
...
}
public class Referencer : IEquatable<Referencer> {
...
public virtual MD5Hash Id { get; set; }
public virtual Referenced Other { get; set } // may be null
...
}
Iタイプリファのオブジェクトをロードしようとすると、NHibernateの行がNULL値を含む場合、それが参照される型 のオブジェクトをインスタンス化しようとするので、キーのNULL値を参照リファに割り当てません、データベース内のReferencerを更新します。 Referencedはnullableカラムに対応するNameプロパティを持っているので、NHibernateは例外を発生させます。私が欲しいのは、NHibernateがOtherプロパティをnullに設定することです。
構造体の代わりにクラスになるようにMD5Hashの定義を変更することができますが、MD5Hashがnullにならないと仮定したコードの場所が不明なため、別の解決策を探しています。
カスタムタイプのコード...
internal class MD5HashType : IUserType {
public SqlType[] SqlTypes {
get { return new[] { new SqlType(DbType.Binary, 16) }; }
}
public Type ReturnedType {
get { return typeof(MD5Hash); }
}
public new bool Equals(object x, object y) {
return Object.Equals(x, y);
}
public int GetHashCode(object x) {
return (null == x) ? 0 : x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner) {
var val = NHibernateUtil.Binary.NullSafeGet(rs, names[0]);
return (null == val || DBNull.Value == val) ? MD5Hash.Empty : new MD5Hash((byte[])val);
}
public void NullSafeSet(IDbCommand cmd, object value, int index) {
var val = (MD5Hash.Empty == ((MD5Hash)value)) ? null : ((MD5Hash)value).ToByteArray();
NHibernateUtil.Binary.NullSafeSet(cmd, val, index);
}
public object DeepCopy(object value) {
return value;
}
public bool IsMutable {
get { return false; }
}
public object Replace(object original, object target, object owner) {
return original;
}
public object Assemble(object cached, object owner) {
return cached;
}
public object Disassemble(object value) {
return value;
}
}
MD5ハッシュIUserTypeのコードは、あなたの質問に答えるのに非常に役立ちます。 –
また、PKとしてのハッシュはひどい考えです。 –
@jamesコードを追加しましたが、それが役立つとは確信していません。 NHibernateのコードを踏んで、NullSafeGetの結果をヌルに対してテストし、デフォルトではではないことがわかりました。また、「保存されていない値」の値に対してテストしません。 –
Faron