NHibernate Сохранение от 0 до много к одному столбцу вместо нуля - PullRequest
3 голосов
/ 22 апреля 2009

У меня есть таблица Donations, в которой есть столбец CampaignID, который относится к таблице Campaigns. Мне нужно вставить 0 в столбец CampaignID вместо Null, если кампания не используется для этого пожертвования.

Мои сопоставления из таблицы пожертвований выглядят так:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
    <class name="Donation,Entities" lazy="true" table="Donations" dynamic-update="true" >
        <id name="DonationID" column="PledgeID" type="Int64">
            <generator class="native" />
        </id>
        <many-to-one name="FundraisingCampaign" class="Campaign, Entities" column="CampaignID" lazy="proxy" not-found="ignore" cascade="none" />

Перед сохранением в базе данных я проверяю, является ли объект Campaign в моем объекте пожертвования нулевым. Если это так, тогда я устанавливаю для него новый объект Campaign и устанавливаю CampaignID = 0 следующим образом.

    if (null == donation.FundraisingCampaign)
    {
        donation.FundraisingCampaign = new Campaign() {CampaignID = 0};
    }

Проблема в том, что я получаю сообщение ErrorMessage «объект ссылается на несохраненный временный экземпляр - сохраните этот временный экземпляр перед сбросом». при попытке сохранить.

Я не понимаю, почему он заботится о чем-либо на моем объекте Campaign, кроме CampaignID, потому что у меня есть cascade = "none", он не должен пытаться что-либо сохранить в таблице Campaign.

Нынешняя система вынуждает меня также установить 0 вместо Null, поэтому сохранение Null не вариант.

Ответы [ 2 ]

3 голосов
/ 22 апреля 2009

Попробуйте загрузить объект Campaign, идентификатор БД которого равен 0, из БД. Тогда это будет полностью постоянный объект. После этого вы сможете установить его и сохранить пожертвование.

Если это работает, вам нужно изменить сопоставление свойств идентификатора объекта Campaign. Nh не может определить, что ваш временный объект кампании создан здесь:

new Campaign() {CampaignID = 0};

на самом деле отдельный объект. Что вы должны сделать, это добавить «несохраненное значение» в ваше отображение, скажем, -1. Теперь Nh может определить разницу между вашей действительной отдельной кампанией с идентификатором БД, равным 0, и переходными новыми кампаниями с идентификаторами -1. Затем не забудьте установить Id для вновь созданных кампаний на -1.

2 голосов
/ 22 апреля 2009
  1. NHibernate знает, сохранена ли сущность, проверяя первичный ключ. Если оно равно 0, оно не сохраняется. Вы можете изменить это поведение в отображении.
  2. Если вы пытаетесь сохранить сущность, все ссылающиеся сущности должны либо каскадно, либо уже сохраняться. Для NHibernate важно брать внешние ключи. Он не может указывать на внешний ключ в вашей памяти, он должен быть в базе данных, поэтому он должен быть сохранен. Если это не так, вы получите сообщение об исключении.

Имея эту информацию, вы должны понять, почему у вас проблема.

Сгенерирован ли CampaignID с автоматическим счетчиком? Тогда это не работает в любом случае. (Вы не можете установить идентификатор в приложении.) Если вы не сохраните Campaign с CampaignID = 0 (см. Ниже).

Вы можете сделать CampaignID обнуляемым int, тогда несохраненное значение будет нулевым по умолчанию.

Имейте в виду, что вы получаете кампанию с CampaignID = 0 в вашей базе данных. Это «Нулевой объект». Вам необходимо сохранить его, например, после настройки базы данных.

Если вы хотите избежать нулевого объекта, вы попадаете в неприятности. Концептуально NHibernate не дает вам доступа к внешним ключам, он управляет ими для вас. Вы, вероятно, можете сделать некоторые трюки (например, в перехватчике), но я думаю, что это не стоит хлопот. Вы также должны убедиться, что нет ограничения внешнего ключа, что тоже нехорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...