Сохранение ссылочной целостности при вставке с помощью NHibernate - PullRequest
3 голосов
/ 22 июня 2010

Я много разобрался с nhibernate, но, похоже, это мое последнее препятствие на пути к непониманию того, что происходит. Так вот в чем проблема.

У меня есть базовая структура базы данных:

Shows:
ID [Pk]
CountryID [Fk]
Name

Countries:
ID [Pk]
Name

CountryID имеет исходную ссылку на ключ от шоу к первичному ключу таблицы стран, и страны уже заполнены предварительно установленными значениями, которые будут редко меняться.

Вот мои файлы картирования

    public ShowMap()
    {
        Table("Shows");

        Id(x => x.ID);
        Map(x => x.Name)

        HasOne<Country>(x => x.CountryOrigin)
            .Cascade.All()
            .ForeignKey("CountryID");
    }

    public CountryMap()
    {
        Table("Countries");

        Id(x => x.ID);
        Map(x => x.Name);
    }

Я почти уверен, что это проблема с отображением, но когда я делаю вставку в шоу, и к ней присоединяется страна. Он пытается вставить новую страну в базу данных вместо использования уже существующей в базе данных . Что, похоже, является главной проблемой. Я не знаю, как правильно выполнить вставку, если она использует существующую запись в БД.

Наконец, вот пример того, как я пытался сделать вставку, не зная, что делать.

        using (var tx = _session.BeginTransaction())
        {

            Show s1 = new Show();
            s1.CountryOrigin = new Country { ID = 2, Name = "Japan" };
            s1.Name = "Liar Game";

            _session.SaveOrUpdateCopy(s1);
            tx.Commit();
            tx.Dispose();
            return true;
        }

Итак, вопрос в том, как вставить новое шоу и сделать так, чтобы оно ссылалось на существующую запись в таблице стран?


Обновление 1 Я переработал его, чтобы использовать отношение «имеет много», потому что я читал, что «есть», вероятно, неправильный путь. Все еще есть та же проблема, вот изменения кода. Они также отражают изменения кода в комментариях.

Код вставки:

        using (var tx = _session.BeginTransaction())
        {

            Show s1 = new Show();
            s1.CountryOrigin.Add(_session.Get<Country>(2));
            s1.Name = "Liar Game";

            _session.SaveOrUpdateCopy(s1);
            tx.Commit();
            return true;
        }

Отображения:

    public ShowMap()
    {
        Table("Shows");

        Id(x => x.ID);
        Map(x => x.Name)

        HasMany<Country>(x => x.CountryOrigin)
            .KeyColumn("ID")
            .Cascade.SaveUpdate();
    }

    public CountryMap()
    {
        Table("Countries");

        Id(x => x.ID);
        Map(x => x.Name);
    }

По-прежнему получение невозможной вставки нуля в CountryID, как упоминалось в одном из комментариев.

Обновление 2 Небольшое тестирование / отладка:

            s1.CountryOrigin.Add(_session.Get<Country>(2));

Делает то, что должен делать, и получает правильную страну, но проблема возникает при вставке. Так что это заставляет меня думать, что это больше проблема картографии.

Ответы [ 2 ]

3 голосов
/ 22 июня 2010

У вас есть отношения один-ко-многим между страной и шоу с шоу со многих сторон. Таким образом, Страна должна отображаться с использованием References:

public ShowMap()
{
    Table("Shows");

    Id(x => x.ID);
    Map(x => x.Name)

    References(x => x.CountryOrigin, "CountryID");
}
0 голосов
/ 22 июня 2010

Вам нужно использовать Session.Load, чтобы получить объект Country:

s1.CountryOrigin = _session.Load<Country>(2);

Session.Load говорит: «Я знаю, что в БД существует запись с этим идентификатором. Создайте для меня прокси-сервер этого объекта, не потрудившись перейти в базу данных». Вы также можете использовать Session.Get, но это создаст дополнительное отключение БД.

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