NHibernate: многие-к-одному - * должны * вы загружаете родительский объект? - PullRequest
4 голосов
/ 29 января 2010

Допустим, следующие классы сущностей:

public class Player
{
 public virtual int ID { get; set; }
 public virtual string Name { get; set; }
 public virtual Team Team { get; set; }
}

public class Team
{
 public virtual int ID { get; set; }
 public virtual string City { get; set; }
 public virtual string Nickname { get; set; }
}

Предположим, следующий класс сопоставления для игрока:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
 <class name="Player">
  <id name="ID" column="ID" type="System.Int32" unsaved-value="null">
   <generator class="native"/>
  </id>
  <property name="Name" column="Name" not-null="true" type="System.String"  length="50" insert="true" update="true"/>
  <many-to-one name="Team" not-null="true" outer-join="auto" insert="true" update="true">
   <column name="TeamID"/>
  </many-to-one>
 </class>
</hibernate-mapping>

И предположим следующий метод репозитория Player:

public void Add(Player player)
{
 using (ISession session = NHibernateHelper.OpenSession())
 {
  using (ITransaction transaction = session.BeginTransaction())
  {
   session.Save(player);
   transaction.Commit();
  }
 }
}

Мой вопрос:

Нужно ли загружать полноценную команду (родительский объект), когда я хочу создать нового игрока?
Или я могу указать «фиктивный» объект и указать только внешний ключ?

Player player = new Player
              {
               Name = "Tom Brady",
               Team = new TeamRepository().GetTeamByCityAndNickname("New England", "Patriots") // Is this the only way?
               // or can I do this?
               // Team = new Team { ID = 22 }
              };
new PlayerRepository().Add(player);

  • И если я не могу указать «макет» объект (указав только внешний ключ), не могли бы вы объяснить почему я не могу?
  • То есть, не могли бы вы дать мне представление о том, что происходит под капотом?

Heads-Up:


  • Интересно, если говорить об EF 4.0 во время эпизода DotNetRocks , Джулия Лерман признал, что многие люди хотят использовать внешний ключ в этих типах ситуаций.

РЕДАКТИРОВАТЬ: Этот ответ указывает на суть моего вопроса.

Думайте об этом как о предмете, который только держит идентификатор и загрузит остальное, если вам когда-нибудь понадобится. Если вы просто передаете его создавать отношения (например, ФК), id - это все, что вам когда-либо понадобится.

  • Ну, если это так, то почему я должен беспокоиться о прокси-объектах и ​​тому подобном? Почему я не могу просто создать «фиктивный» объект и указать значение внешнего ключа, если это все, что действительно имеет значение?

Ответы [ 2 ]

4 голосов
/ 29 января 2010

вы используете внешний ключ, как так ...

Team = session.Load<Team>(id);

знать разницу между загрузкой и получением

3 голосов
/ 29 января 2010

Если у вас есть доступ к сеансу на данный момент, вы можете позвонить

Team = Session.Load<Team>(id);

Предпосылка Load заключается в том, что он создаст прокси-сервер NHibernate, который может разрешить себя при необходимости. Конечно, вы должны быть уверены, что идентификатор существует, иначе вы получите ошибку EntityNotFound, если она попытается разрешить себя сама.

...