Search code examples
c#nhibernatehibernate-criteria

NHibernate and C#: error using nested properties with Criteria


The scenario is a MVC.NET application using NHibernate to interact with a SQL Server database.

Every NHibernate query with Criteria works fine, except for the last I have added, that give the following error:

could not resolve property: Reading.Truck.Company.CompanyId of: ADO.Alarms

Related code is the following:

session = NHibernateSessionManager.Instance.GetSession();
            ICriteria criteria = session.CreateCriteria(typeof(Alarms));
            criteria.Add(Expression.Eq("Reading.Truck.Company.CompanyId", companyId));

            alarmsList = criteria.List<Alarms>();

Nested properties are defined in related class file like this: Alarms.cs

private AlarmsReading _Reading;  
public AlarmsReading Reading
    {
        get { return _Reading; }
        set { _Reading= value; }
    }

These properties are defined in mapping files like this:

Alarms.hbm.xml

<hibernate-mapping  ...>
<class name="Alarms" table="Alarms" lazy="false">
<cache usage="read-write"/>
...
<many-to-one name="Reading" class="AlarmsReading">
  <column name="Reading_Id" not-null="true"/>
</many-to-one>
...
</class>
</hibernate-mapping>

All other criteria query, with other nested properties, defined same way, works fine.

Strange thing is if I use normal IQuery syntax with createQuery method, all works smoothly; that is:

session = NHibernateSessionManager.Instance.GetSession();
IQuery query = null;
query = session.CreateQuery("FROM Alarms al WHERE Reading.Truck.Company.CompanyId = (:companyId) ");
query.SetParameter("companyId", companyId);
alarmsList = query.List<Alarms>();

I've also find this similar question, and I know there are various way to solve, but I'm looking for the cause of this misbehaviour.

Any help will be appreciated. Thank you in advance.


Solution

  • Ok. I've understood how to use Criteria properly, reading answers to this post, and following this example on the NHibernate official site.

    Dot notation with Criteria seems to work only for the components of the current object (and their properties: i.e. Reading.ReadingId).

    If we want to reach deeper properties we would use Associations.

    So this code works fine for my task:

    session = NHibernateSessionManager.Instance.GetSession();
    ICriteria criteria = session.CreateCriteria(typeof(Alarms));
    criteria.CreateCriteria("Reading").CreateCriteria("Truck")
            .Add(Expression.Eq("Company.CompanyId", companyId));
    
    alarmsList = criteria.List<Alarms>();