2010-06-22 2 views
3

Я много размышлял о nhibernate, но это, кажется, мое последнее препятствие, не понимая, что происходит. Так вот проблема.Поддержание ссылочной целостности при вставке с помощью NHibernate

У меня есть основной databas структура:

Shows: 
ID [Pk] 
CountryID [Fk] 
Name 

Countries: 
ID [Pk] 
Name 

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

Вот мой Mapping Files

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; 
     } 

Таким образом, вопрос, как я могу вставить новое шоу и это ссылаться на существующую запись в таблице стран?


Update 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, как было отмечено в одном из комментариев.

Update 2 Doing некоторые немного тестирования/отладки:

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

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

+0

Только педантичная точка: вам не нужно 'tx.Dispose()'. Оператор 'using' вызовет' Dispose() 'для вас. –

+0

это правда, даже если я вернусь сразу после tx.dispose? – percent20

+0

Да, он все равно будет распоряжаться. –

ответ

3

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

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

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

    References(x => x.CountryOrigin, "CountryID"); 
} 
+0

Спасибо, что это решило. И ваше описание этого на самом деле заставляет меня лучше понять, как работает справочник. Хорошее короткое и простое объяснение. Благодарю. – percent20

0

Вы должны использовать Session.load, чтобы получить объект Страна:.

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

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

+0

Вот что я думал о том, что я читал, но когда я пробую этот код, я получаю. «Невозможно вставить значение NULL в столбец« CountryID »как ошибку для вставки. Вот почему я так смущен. Хотя я думал, что нашел ответ, и общепринятая мудрость говорит, что он должен работать, это не так. – percent20

Смежные вопросы