views:

1306

answers:

3

I have a class that is mapped to a table using NHibernate. The problem is that only some of the properties are mapped to columns in the table. This is fine because the only columns we use for display are mapped, however I was wondering if there is any way to query against other columns in the table that aren't mapped to properties in my class.

For example we have a table with the following columns:

Customer
-----------
CustomerId
Name
DateCreated

and we have an object

public class Customer
{
    public virtual int CustomerId {get;set;}
    public virtual string name {get;set;}
}

and name and customerId are mapped however DateCreated is not because we never display it anywhere. We would like to query the Customer table for customers that were created by a certain date. Is there any way to do this without mapping the DateCreated? Also it would be preferrable to do this using the criteria API.

+2  A: 

Is using a plain SQL query out of the question? I'm not able to test it right now, but I would imagine that you could query on unmapped fields, as long as your query returns something that Hibernate can map to an object. (sorry if this was already ruled out as an option)

EDIT: This seems to work:

ISQLQuery query = session.CreateSQLQuery(
                "select c.* " +
                "from Customer c " +
                "where c.CreateDate > :CreateDate");

query.SetDateTime("CreateDate", new DateTime(2009, 3, 14));
query.AddEntity(typeof(Customer));

IList<Customer> results = query.List<Customer>();
Andy White
(my column names were slightly different)
Andy White
it's not out of the question but I'd really like to be able to use the criteria api if at all possible. Thanks for the post
lomaxx
+1  A: 

With HQL/Criteria queries, NHibernate can only work with what has been mapped (although raw SQL is still an option as Andy White has pointed out). If you want to use Criteria queries, you have to map the column.

However, NHibernate is not restricted to using publicly accessible members. So, if you want to keep hiding the CreateDate field, declare a private (maybe read-only?) property. Alternatively, you can skip the property and instruct NHibernate to use field level access by setting access="field" on the property element in the mapping.

I know you wanted to do this without mapping the field, but I just don't think it's possible (without modifying the NHibernate source ;). Still, if you're querying against the field then the field has some relevance to your domain and therefore probably deserves to be mapped into it, and with a private or protected member you can keep the information hiding in place.

Stuart Childs
+4  A: 

Ayende Rahien posted an article which describes specifying access="noop" in the mapping to specify query-only properties. See NHibernate – query only properties. I have not tried this myself.

Mike Henry
It works really nicely and really easy to setup.
Goblin