【发布时间】: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