Можно ли сохранить отношение OneToOne к иерархии классов с помощью JoinedBase? - PullRequest
1 голос
/ 15 декабря 2009

Я бы хотел, чтобы одна из моих сущностей имела отношения один-к-одному с иерархией классов. Думайте об этом как о шаблоне Стратегии, где каждая стратегия нуждается в различных параметрах для сохранения. Я пытался использовать комбинацию OneToOne и JoinedBase / JoinedKey, но я столкнулся с проблемой.

При этой комбинации первичный ключ основного объекта также отображается как первичный ключ таблицы, представляющей корневой класс в иерархии, и как первичный ключ подкласса:

        Order    --------------- TaxCalculator
([PrimaryKey]Id = 1234)        ([PrimaryKey(PrimaryKeyType.Foreign)]OrderId = 1234) 
                                      ^
                                      |
                                      |
                             UkTaxCalculator
                      ([JoinedKey]UkTaxCalculatorId = 1234)

Я могу сохранить это нормально, но потом я не могу изменить, какой подкласс TaxCalculator у меня есть. Когда я делаю что-то вроде:

order.TaxCalculator = new OverseasTaxCalculator(order);

затем попытайтесь сбросить, тогда ActiveRecord / NHibernate (понятно) становится недовольным, что теперь есть два TaxCalculators с Id = 1234.

Я могу обойти это, заменив OneToOne на HasMany / BelongsTo и скрыв множественность от пользователей объекта Order, но мне интересно знать, возможно ли это сделать с OneToOne.

Полный пример кода на github . Этот код вызывает исключение, когда второй SessionScope удаляется. Если вы клонируете проект, он должен запускаться «из коробки».

Ответы [ 2 ]

1 голос
/ 16 декабря 2009

Прежде всего извините, но я не пробовал свое решение. Уже поздно, и мне действительно нужно спать ;-). Я думаю, что единственный способ, которым один-к-одному мог бы работать, был бы подходом «таблица на иерархию», используя столбец дискриминатора вместо таблицы на подкласс. Возможно, это позволит вам преобразовать существующий объект в другой подкласс. Иначе, как вы сказали, что-то вроде полиморфного удаления-сироты, к сожалению, не поддерживается. Так что я думаю, это будет ваш (очень) последний вариант.

Но если это не удается, почему бы вам не отобразить его как один-ко-многим вместо многих-к-одному с внешним ключом в таблице заказов, повторно используя TaxCalculators? Я бы вообразил их довольно статичными.

Интересная идея: полиморфное удаление-сирота.

0 голосов
/ 16 декабря 2009

Мы делаем нечто очень похожее на то, что вы пытаетесь сделать. Я думаю, что именно ваша комбинация «один-к-одному» и объединенного ключа вызывает проблему. Попробуйте это:

[ActiveRecord, JoinedBase]
public class TaxCalculator
{
    protected int TaxCalculatorId;

    [PrimaryKey]
    public virtual int Id
    {
        get { return TaxCalculatorId; }
        set { TaxCalculatorId = value; }
    }

    // common tax calculation fields, methods etc...
}

[ActiveRecord]
public class OverseasTaxCalculator : TaxCalculator
{
    [JoinedKey]
    public override int Id
    {
        get { return TaxCalculatorId; }
        set { TaxCalculatorId = value; }
    }

    // overseas tax calculation specific methods, properties etc...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...