views:

206

answers:

2

Assume the following entity classes:

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

Assume the following mapping class for 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>

And assume the following Player repository method:

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

My question:

Must I load a full-fledged Team (parent object) when I want to create a new Player?
Or can I specify a "mock" object, and only specify the foreign key?

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

  • And if I can't specify a "mock" object (specifying only the foreign key), can you please explain why I can't?
  • That is, can you please give me an idea about what's going on under the hood?

Heads-up:


  • Interestingly, when speaking about EF 4.0 during a DotNetRocks episode, Julia Lerman acknowledged that many people want to use the foreign key in these types of situations.

EDIT: This answer points to the essence of my question.

Think of it like having an object that only keeps the Id and that will load the rest if you ever need it. If you're just passing it arround to create relationships (like FKs), the id is all you'll ever need.

  • Well if that's the case, then why do I need to be worried about proxy objects and such? Why can't I just create a "dummy" object and specify the foreign key value if that's all that really matters?
+3  A: 

you use the foreign key like so...

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

know the difference between load and get

dotjoe
Yes - I understand that this is the convention, but I'm wondering if this is the *only* way; and if so, I'd like to know why.
Jim G.
I answered a question around this before http://stackoverflow.com/questions/1765165/nhibernate-update-reference/1765464#1765464. The only other option is to fiddle with the ID and that goes against NHibernate best practices that suggest that the Id should be readonly.
Michael Gattuso
@Michael Gattuso: Thanks for filling me in.
Jim G.
+2  A: 

If you have access to Session at this point you can call

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

The premise of Load is that it will create an NHibernate proxy that can resolve itself if needed. Of course you have to be sure the id exists or you will get an EntityNotFound error if it ever tries to resolve itself.

Michael Gattuso