4

假设以下实体类:

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

假设 Player 有以下映射类:

<?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);

  • 如果我不能指定一个“模拟”对象(只指定外键),你能解释一下为什么我不能吗?
  • 也就是说,你能给我一个关于引擎盖下发生了什么的想法吗?

小心:



编辑: 这个答案指向我问题的本质。

把它想象成有一个只保留 Id 的对象,如果你需要它会加载其余的。如果您只是传递它来创建关系(如 FK),那么 id 就是您所需要的。

  • 好吧,如果是这样的话,那我为什么需要担心代理对象之类的呢?如果这真的很重要,为什么我不能只创建一个“虚拟”对象并指定外键值?
4

2 回答 2

4

你像这样使用外键......

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

知道load和get的区别

于 2010-01-28T21:25:11.153 回答
3

如果您此时可以访问 Session,您可以致电

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

Load 的前提是它会创建一个 NHibernate 代理,如果需要,它可以自行解析。当然,您必须确保 id 存在,否则如果它尝试自行解决,您将收到 EntityNotFound 错误。

于 2010-01-28T21:28:38.580 回答