开发者

One to many mapping. NHibernate

I was looking at 'NHibernate 3 Beginner's Guide' book and found interesting tip:

开发者_JAVA百科

In a real life inventory application, you will probably want to avoid putting a Products collection on the Category entity, as it is possible that a category can have hundreds, if not thousands, of associated products. To load the whole, huge collection of products for a given category would be unwise and would lead to an application having unsatisfactory response times.

Tip was right after an example of one-to-many relationships building. The entities were Product and Category. The example is quite straightforward:

public class Category : Entity // Entity probably contains an `Id` property
{
    private List<Products> products;

    public String CategoryName { get; set; }
    public String Description  { get; set; }
    public IEnumerable<Product> Products { get { return products; } }
}  

public class Product : Entity
{
    public Decimal UnitPrice { get; set; }
    public String ProductName { get; set; }
    public Category Category { get; set; }
}

So what is the real life example of one-to-many relationships?

Would it be enough for the example just to put Category inside a product entity as a String property?


The idea is that if you avoid the IList property all-together, you can still get to the products for a category e.g. like the following:

var products = session.QueryOver<Product>().Where(p => p.Category == someCategory).List();

But you now have the possibility to do paging, filtering, getting the top product etc.:

var product = session.QueryOver<Product>().Where(p => p.Category == someCategory).OrderBy(p => p.Relevance).Take(1).SingleOrDefault();

which you do not have if it is a simple IList property. In general (in my experience), the less two-way ascociations you have, the better your querying granularity will be. Also, it reduces your complexity when it comes to saving.


You may want to have a look a the lazy property of Nhibernate.It allows you not to load that property always unless we explicitly asks for it.

Nhibernate Lazy


Let's ask different question: what if your application should present categories in tree-view control, which upon expanding category node will list all products? When you want to display all products there's no other way than ... actually querying database and loading all products.

That's actually pretty common real-life scenario and one of easiest approaches is indeed to simply have Category.Products property. Of course there's nothing wrong with having such property, but the real question is how you should manage those objects.

Luckily, you don't have to pull all the products with single category pull. Category.Products can be marked to load lazily (as opposed to eagerly, more information can be found here). What this means is, loading category won't query database for its products. Instead, NHibernate will create proxy object for Products, which can be initialized later - when they are actually needed (think user expanding category node).


And to answer your question...

If single product is bound to exactly one category, then it's good real-life one-to-many relation example. However, if product can be described by more than one category, it's many-to-many relation then.


I think the quote will say that you should not use the Products property in Category class at all.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜