1

私はNHibernateの実験を始めたばかりで、次のシナリオに頭を悩ませることができませんでした.誰かがそれに光を当ててくれることを願っています. ありがとうございました。

既存のデータ アクセス レイヤーを Subsonic から NHibernate にリファクタリングしたいと考えています。既存のデータベースはBINARY(16)主キーとして使用しています。Subsonic では、byte[] を主キーとして問題なく処理できます。NHibernate でデータ型を持つプロパティをマップしようとするとbyte[]、次の例外メッセージが表示されます。

{"Illegal use of an array as an identifier (arrays don't reimplement equals)."}

私のエンティティとマッピングの例 (FluentNHibernate を使用) は次のとおりです。

    public class Product
    {
        public virtual byte[] Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Description { get; set; }
    }

.

    public ProductMapping()
    {
        Table("tblProduct");
        Id(p => p.Id).Column("prdProductGuid");
        Map(p => p.Name).Column("prdName");
        Map(p => p.Description).Column("prdDescription");
    }

この問題を回避する方法はありますか? ありがとうございました。

現在、.NET 4.0、NHibernate 3.3.1、および MySQL 5.1.52 を使用しています。

4

3 に答える 3

2

見た目よりずっと簡単だと思います。16 バイト。ほとんどの場合、GUID (一意の識別子) を表します。奇妙で神秘的なバイト配列よりも ID の方が理にかなっている...

GUID タイプの ID を持つように C# クラスを変更するだけです

public class Product
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
}

残りは NHibernate の内部で行われます。

于 2012-10-28T08:32:31.120 に答える
0

コンポーネントを複合キーとして使用できるはずです。コンポーネントは、プロパティとして byte[] のみを持ちますが、GetHashCode() および Equals() の便利な実装を提供できます。

于 2012-10-28T17:23:55.040 に答える
0

Hibernate コミュニティを調べたところ、を利用するためのヒントIUserTypeが見つかりました。

基本的にバイト配列のシリアル化されたラッパーであるカスタムクラスBytesを作成しました。

[Serializable]
public class Bytes
{
    private byte[] _value;
    public byte[] Value { get { return _value; } }

    public Bytes(byte[] bytesValue)
    {
        _value = bytesValue;
    }

    public override bool Equals(object obj) {...}
    public override int GetHashCode() {...}
    public override string ToString() {...}
}

BytesUserType :

public class BytesUserType : IUserType
{
    private static readonly NHibernate.SqlTypes.SqlType[] _sqlTypes = { NHibernateUtil.Binary.SqlType };
    public NHibernate.SqlTypes.SqlType[] SqlTypes { get { return _sqlTypes; } }
    public Type ReturnedType { get { return typeof(Bytes); } }
    public bool IsMutable { get { return false; } }

    public object NullSafeGet(IDataReader dr, string[] names, object owner)
    {
        object obj = NHibernateUtil.Binary.NullSafeGet(dr, names[0]);
        if (obj == null)
            return null;
        var value = (byte[])obj;
        return new Bytes(value);
    }

    public void NullSafeSet(IDbCommand cmd, object obj, int index)
    {
        if (obj == null)
            ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
        else
        {
            Bytes a = (Bytes)obj;
            byte[] valueBytes = a.Value;
            ((IDataParameter)cmd.Parameters[index]).Value = valueBytes;
        }
    }

    public new bool Equals(object x, object y) {...}
    public object DeepCopy(object value) {...}
    public int GetHashCode(object x) {...}
    public object Replace(object original, object target, object owner) {...}
    public object Assemble(object cached, object owner) {...}
    public object Disassemble(object value) {...}
}

エンティティとマッピングを更新しました:

public class Product
{
    public virtual Bytes Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
}

.

public ProductMapping()
{
    Table("tblProduct");
    Id(p => p.Id).Column("prdProductGuid").CustomType<BytesUserType>();
    Map(p => p.Name).Column("prdName");
    Map(p => p.Description).Column("prdDescription");
}

そして、それはトリックです!

于 2012-10-29T07:01:26.607 に答える