views:

557

answers:

2

I've formerly used L2S and am looking at using NHib along with the Sharp Architecture on a project. I've started prototyping and come up against the first issue which i have no idea how to google for.

Given a POCO with some simple properties, and one reference property (Category - class not shown here):

public class Post
{
  public Post()
  {
    this.DateCreated = DateTime.Now;
  }

  public virtual string Title {get;set;}
  public virtual DateCreated {get;set;}
  public virtual Category {get;set;}
}

This is handy if i want to say produce a summary of posts in tabular format - if i want a column named "Category" and i want to show the category title i can simply use Post.Category.Title.

However a user creates a new post (they select a category from a drop down list or similar). They click submit, and i new up a Post object. However before i can persist the new Post, i have to retrieve an instance of the Category (by id) to assign to the Category property?

How to get the best of both worlds? If i update the Post POCO, making the Category an int, I've made it simpler to create new instances. But harder for some rendering code which will now have to resolve the category name given the Id?

I feel i'm missing some basic concept here?

I know with Linq to Sql given a schema where the Post table had an integer foriegn key column named CategoryId, would generate me both the underlying table column (CategoryId) and and EntitySet which contained the foreign key row.

How to acheive similar in NHibernate? How is this generally managed?

Thanks

+3  A: 

Associated entities should be mapped as entities - e.g. Category, not int CategoryId.

When you're creating a new Post, if you don't have an actual Category instance (and why not? if you're picking categories from a list you've already loaded them) but only have its id you can use a Load() method to get a persistent Category instance for given id without actually hitting a database:

post.Category = (Category) sesssion.Load(typeof(Category), categoryId);

You can also use the generic version:

post.Category = session.Load<Category>(categoryId);
ChssPly76
@Justice - thank you for editing
ChssPly76
Thanks for replying. This scenario is web (asp.net mvc) and i'm looking at trying to avoid too many lookups to the Db on postback *just* to repopulate essentially lookup or referential data in order to persist an entity which may have many associated entities.The Load method looks great (and i SHOULD have thought about it but as a newbie i need to get more familiar with NHib - the book is on its way).
6footunder
A: 

In NHibernate, you would use a reference property.

Using fluent mapping, it looks something like this:

mapping.References(x => x.Category, "CategoryId").PropertyRef(x=>x.Id).Cascade.All();

in XML, it's roughly

<many-to-one name="Category" column="category_id" class="YourNamespace.Category" cascade="all" property-ref="Id" />

You can use not-found to pick the behavior when there's no associated category.

Essentially, you want the semantics of the category object, not the ID, so you just tell NHibernate how they are associated.

JasonTrue
Sry, excuse my slowness... the PropertyRef has what effect? I've just googled again and fluentnhibernate propertyref doesn't dredge up much that looks useful :-)
6footunder
In this case, it references the Id property of the Category object, binding it to the CategoryId column in Post. (I should probably have used category_id to be consistent with my xml mapping example).
JasonTrue