Hi guys,

I am developing a web application in C# using NHibernate and Flex for
UI. I recently ran into a performance issue which made me have second
thoughts regarding the way I used NH so far.

Say there are 2 entities having properties:
* class Person { Id, FirstName, LastName, P1.... Pn }
* class Cat { Id, Name, Owner, P1 ... Pn } // a cat is owned by a
person; owner is lazy loaded

Both entities are fully mapped to database (by which I mean classes
are mapped to tables and all their properties are mapped to columns),
so when I want to get a cat by Id I get this query:
* SELECT Id, Name, OwnerId, P1, ... Pn FROM Cat WHERE Id = x.
Let's say this is what users want to see most of the time.

But there's this scenario: how about showing the names of ALL cats and
their owners' names? Doesn't matter if there are thousand of cats, the
user wants to see them all. And yes, there are thousands of cats!

What I did so far (and now I think it's SO bad):
* var allCats = session.CreateCriteria<Cat>()
*    .SetFetchMode("Owner", FetchMode.Join)
*    .List<Cat>();

This is a waste of performance: the query selects ALL columns from
both tables; I only needed 3 columns:
- 1 from Cat (Name)
- 2 from Person (FirstName, LastName)
That's 3 vs 2*(n + 3); for thousands of records I get a ton of useless
data.

So I figured I should use projections:
* var criteria = session.CreateCriteria<Cat>()
*    .CreateAlias("Owner", "owner")
*    .SetProjections(
*         Projections.Property("Name").As("CatName"),
*         Projections.Property("owner.FirstName").As
("OwnerFirstName"),
*         Projections.Property("owner.LastName").As("OwnerLastName"));
* var data = criteria.List<Cat>();

This is where trouble begins: I can't get a list of cats! The best I
can get is a IList<CatDto>:
* criteria.SetResultTransformer(Transformers.AliasToBean<CatDto>());
* var data = criteria.List<CatDto>();
where CatDto is defined as:
* class CatDto { CatName, OwnerFirstName, OwnerLastName }

I must admit I gained a performance boost on the query side, but I
ended up with a DTO and I'm not sure if this is the right way to do
it. I'm not happy with:

1) duplicated structure: CatDto should have all the properties of Cat
and of its associations; of these, only 1 is set in this scenario; but
maybe I should have a different DTO for each type of request? (e.g.
CatDtoForShowingNames)

2) flattened hierarchy. cat.Owner.FirstName becomes
catDto.OwnerFirstName. What about cat.Owner.A.B.C....Z? Should DTOs
reflect the hierarchy of entities, such as catDto.OwnerDto.FirstName?
If so, could I get such an object from criteria?

3) Why doesn't this work:
* criteria.SetResultTransformer(Transformers.AliasToBean<Cat>());
* var cats = criteria.List<Cat>();
It would just set the cat's name, create an owner for it using
reflection and set its first/last name...No need for DTOs whatsoever.

Please correct me if you think I am wrong, I'm just a beginner
anyway :) and please let me know what is the best way to handle this.
Thank you!

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to