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)”的内部异常是什么?我的理论是“复合 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 回答