【问题标题】:NHibernate: Many-to-One - *Must* You Load the Parent Object?NHibernate:多对一 - *必须*您加载父对象?
【发布时间】:2011-01-10 14:40:37
【问题描述】:

假设以下实体类:

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

  • 如果我不能指定“模拟” 对象(仅指定 外键),你能解释一下吗 为什么我不能?
  • 也就是说,您能告诉我引擎盖下发生了什么吗?

单挑:


  • 有趣的是,在谈到 EF 时 4.0 在DotNetRocks episode 期间,Julia Lerman 承认很多人都想 在这些类型中使用外键 情况。

编辑: This answer 指出了我问题的本质。

把它想象成有一个对象 只保留ID,这将加载 其余的,如果您需要的话。如果 你只是把它传递给 创建关系(如 FK), id 就是你所需要的。

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

【问题讨论】:

  • 在我了解 Load 之前,我正在使用所谓的虚拟对象。它确实有效......但不建议这样做。所以你想知道为什么不建议这样做?这是个好问题。
  • @dotjoe:听起来我们在同一个阵营。 :) // 可以这么说,我从来没有接受过正式的“NHibernate 最佳实践”教育(如果不是我们所有人都属于这个阵营的话,可能大多数人)。但无论如何,我想稍微打开这个黑匣子,了解推荐的最佳做法背后的“原因”。
  • 哈哈我也没有......我只是从 NHibernate 网站上关注了那个重击初学者的示例项目。然后我开始查看关于 SO 的问题并关注 Ayende 的博客。

标签: nhibernate loading internals object-persistence


【解决方案1】:

如果您此时可以访问 Session,则可以调用

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

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

【讨论】:

    【解决方案2】:

    你像这样使用外键...

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

    知道difference between load and get

    【讨论】:

    • 是的 - 我知道这是惯例,但我想知道这是否是 only 方式;如果是这样,我想知道为什么。
    • 我在stackoverflow.com/questions/1765165/nhibernate-update-reference/… 之前回答了一个与此相关的问题。唯一的其他选择是摆弄 ID,这违反了建议 Id 应该是只读的 NHibernate 最佳实践。
    • @Michael Gattuso:感谢您填写。
    猜你喜欢
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多