tags:

views:

573

answers:

5

How can you get a single column back from a query instead of a whole object?

I could do something like this to get the whole object, but all I want is the names:

IList<Tribble> tribbles = session.CreateCriteria(typeof(Tribble)).List<Tribble>();
IList<string> names = new List<string>();
foreach (Tribble t in tribbles) {
    names.Add(t.Name);
}

Update #1: I would like to be able to specify additional criteria, so is it possible to just exclude certain columns from being retrieved?

Update #2: See my answer below for the answer I discovered.

+1  A: 

NHibernate is an OR mapper, and its purpose is to map database table data to objects. OR mappers are not generally designed to be general-purpose data query engines, thats ideally what databases are for. If you need to select a large set of single values, like a name, then your best option is to write a stored procedure that will return the required information.

When using ORM's, its always important to remember: Use the right tool for the job. Don't force a tool to serve a purpose it wasn't designed for.

jrista
A: 

You typically don't. It rarely makes sense to have a partially populated business object.

Why would you want to do this?

Jamie Ide
I am using it throughout the entire program with dozens of classes, this is the only time I've needed to do this and it is necessary in this circumstance.
Kevin Albrecht
Can you explain further what the use case is?
Jamie Ide
Doesn't this happen all the time? For example, I want to display an Employee's details plus the name of its Office. I don't need the whole office, just the name.
cbp
@cbp: It does happen all the time. Assuming that Employee is mapped m:1 to Office, NHibernate will retrieve Office when the Employee is loaded using a join. When working with business objects you always return fully populated objects (there are exceptions, of course). That's just the way it is with object oriented programming.
Jamie Ide
+2  A: 

What about executing a query by string?

IList<string> names = session.CreateQuery("select name from Tribbles").List<strings>();
Moskie
Technically, you actually would have to do this: IList<string> names = session.CreateQuery("select t.name from Tribbles t").List<strings>();
Kevin Albrecht
+1  A: 

You can do something like this :

        IQuery query = dao.GetQuery("SELECT u.Id FROM UserImpl u WHERE u.UserName = :username");
  query.SetParameter("username", username);
  return (long)query.UniqueResult();
Shiva
+4  A: 

Here is the solution I eventually ended up using:

ICriteria c = session.CreateCriteria(typeof(Tribble));
c.SetProjection(Projections.ProjectionList().Add(Projections.Property("Name")));
IList<string> names = c.List<string>();

I got this idea from this old StackOverflow question.

Kevin Albrecht