views:

170

answers:

1

I am using ASP.NET-MVC and nHibernate for the first time. Great tools, but big learning curve!

I have a list view of objects that are quite large (each has about 60 properties). In the list view I am only using about 10 of these properties. Performance is not too bad, but it seems a waste to fully hydrate these objects. What is the recommended practice?

I tried using HQL to select fewer properties, but it seems like it won't partially hydrate an object. I also tried making property on the main object that was a header class with the list view properties, but I couldn't seem to get it mapped properly. I think this should be easy but I've really been struggling with it.

EDIT: I kept coming back to this because I knew Anton had given me the answer and I just couldn't see it.

There are three things you need to do:

  1. Make an object with the properties you want.
  2. Make a mapping file to import this object.

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Core.Entities" assembly="Core" default-access="property">
    <import class="RequestHeader" />
    </hibernate-mapping>

  3. If you are using HQL, your object must contain a constructor with all the properties, in the same order, as your select new statement. If you use the Criteria API, you don't need to do this.

    public IList<RequestHeader> ListAll()
    {
        using (ISession session = GetSession())
        {
            using (ITransaction tx = session.BeginTransaction())
            {
                IList<RequestHeader> results = session.CreateCriteria(typeof (Request), "r")
                    .CreateCriteria("Requestor", "req", JoinType.InnerJoin)
                    .CreateCriteria("r.Grant", "g", JoinType.InnerJoin)
                    .SetProjection(Projections.ProjectionList()
                        .Add(Projections.Property("r.Id"), "Id")
                        .Add(Projections.Property("r.Status"), "Status")
                        .Add(Projections.Property("r.SubmissionDate"), "SubmissionDate")
                        .Add(Projections.Property("req.Name"), "Requestor")
                        .Add(Projections.Property("g.Number"), "Number"))
                    .SetResultTransformer(Transformers.AliasToBean(typeof (RequestHeader)))
                    .SetMaxResults(10000)
                    .List<RequestHeader>();
                tx.Commit();
                return results;
            }
        }
    }
    
+1  A: 

60 properties is too much. See Component mapping.

As for selecting a subset of properties, see this: you need a select new HQL construct. Be aware, though, that you need an appropriate constructor and that an object you'll get cannot be saved back to the DB.

Anton Gogolev
Thanks. I had read both your links, but was at a point where the more I read, the more confused I got. I am finally starting to grok the ORM concept though. I recommend the "Summer of nHibernate" videos by Steve Bohlen to anyone getting started.
Leslie