Причины CompositeId Не удалось скомпилировать ошибку документа сопоставления - PullRequest
8 голосов
/ 27 октября 2011

Я пытаюсь использовать 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 не уникален.

Есть ли другой способ сопоставить таблицу с составным первичным ключом?

Спасибо

Мэтью МакФарланд

1 Ответ

27 голосов
/ 27 октября 2011

Что является внутренним исключением для «Не удалось скомпилировать документ сопоставления: (XmlDocument)»? Моя теория заключается в том, что «составной идентификатор класса должен переопределять Equals (): YOURNAMESPACE.PriorityListPart».

Для объектов, которым требуются составные идентификаторы, в качестве ключа используется сам объект. Чтобы объекты, которые «одинаковы», были распознаны как таковые, вам необходимо переопределить методы 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.

...