8

CompositeIdを使用してレガシーシステムにマップしようとしています。ソースデータベースには複合主キーがあるため、通常のthis.Idマッピングを使用できません。

これが私の試みです:

public PriorityListPartMap()
{
    this.Schema("EngSchedule");

    this.Table("vPriorityListPart");

    this.CompositeId().KeyProperty(x => x.AssemblyPartNumber).KeyProperty(x => x.PartNumber);

    this.Map(x => x.CurrentDueDate);

    this.Map(x => x.OrderLine);

    this.Map(x => x.OrderNumber);

    this.Map(x => x.PartDescription);

    this.Map(x => x.ProductCode);

    this.Map(x => x.Revision);
}

セッションファクトリを作成しようとすると、このマッピングによりエラーが発生します:マッピングドキュメントをコンパイルできませんでした:(XmlDocument)

CompositeIdマッピングを削除して、次のように置き換えてみました。

this.Id(x => x.AssemblyPartNumber).GeneratedBy.Assigned();

エラーはそのマッピングで解消されますが、AssemblyPartNumberが一意ではないため、実際には使用できません。

複合主キーを使用してテーブルにマップする別の方法はありますか?

ありがとう、

マシューマクファーランド

4

1 に答える 1

31

「マッピングドキュメントをコンパイルできませんでした:(XmlDocument)」の内部例外は何ですか?私の理論では、「composite-idクラスはEquals()をオーバーライドする必要があります:YOURNAMESPACE.PriorityListPart」です。

複合IDを必要とするエンティティの場合、オブジェクト自体がキーとして使用されます。「同じ」オブジェクトがそのように認識されるようにするには、EqualsメソッドとGetHashCodeメソッドをオーバーライドする必要があります。

エンティティのEqualsメソッドの例は、次のようになります。

public override bool Equals(object obj)
{
    var other = obj as PriorityListPart;

    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;

    return this.AssemblyPartNumber == other.AssemblyPartNumber &&
        this.PartNumber == other.PartNumber;
}

エンティティのGetHashCodeメソッドの例は次のようになります。

public override int GetHashCode()
{
    unchecked
    {
        int hash = GetType().GetHashCode();
        hash = (hash * 31) ^ AssemblyPartNumber.GetHashCode();
        hash = (hash * 31) ^ PartNumber.GetHashCode();

        return hash;
    }
}

これは、オブジェクトを取得する場合、それを実行するための単一のキーを持つことができないことも意味します。複合キーコンポーネントを含む特定のオブジェクトを適切に取得するために使用するキーは、実際には、取得するエンティティに複合キーコンポーネントが設定されたオブジェクトのインスタンスです。

これが、Equals()メソッドをオーバーライドする必要がある理由です。これにより、NHibernateは、Equalsメソッドで指定した内容に基づいて、実際に取得しようとしているオブジェクトを判別できます。

于 2011-10-27T16:14:40.430 に答える