Fluent NHibernate – NHibernate.QueryException: could not resolve property

fluent-nhibernatemappingnhibernatequeryover

To start, yes, there are tons of similar questions here on Stack Overflow, but I've browsed them all and the problems that plague most of them look correct on my issue.

Basically, I'm trying to access an Object's Object via my query, and that could be the problem: is that not allowed? I can access the Id field, always, but any other member variable cannot be accessed.

Here are my Objects:

public class Logfiles
{
    public virtual int Id { get; set; }
    public virtual bool IsActive { get; set; }
    public virtual DateTime LastReference { get; set; }
}

public class LogMerges
{
    public virtual int Id { get; set; }
    public virtual DateTime CreationDate { get; set; }
    public virtual Logfiles Logfile { get; set; }
}

And here are my mappings:

class LogfilesMap : ClassMap<Logfiles>
{
    public LogfilesMap()
    {
        Not.LazyLoad();
        Table("logfiles");
        Id(x => x.Id, "id").Not.Nullable().Unique().GeneratedBy.Identity().UnsavedValue(0);
        Map(x => x.IsActive, "is_active").Not.Nullable().Default("true");
        Map(x => x.LastReference, "last_reference").Not.Nullable();
    }
}

class LogMergesMap : ClassMap<LogMerges>
{
    public LogMergesMap()
    {
        Not.LazyLoad();
        Table("logmerges");
        Id(x => x.Id, "id").Not.Nullable().Unique().GeneratedBy.Identity().UnsavedValue(0);
        Map(x => x.CreationDate, "creation_date").Not.Nullable();
        References(x => x.Logfile, "logfile_id");
    }
}

My table and columns have the names:

logfiles  - id, is_active, last_reference
logmerges - id, creation_date, logfile_id

My code that I'm using to query:

var query = session.QueryOver<LogMerges>()
    .Where(log => log.Logfile.IsActive == true);
IEnumerable<LogMerges> logmerges = query.List().OrderBy(c => c.CreationDate);

Performing the Query causes the error and generates:

NHibernate.QueryException: could not resolve property: Logfile.IsActive of: LogMerges

The only thing I can guess is that I'm not allowed to do the "log.Logfile.IsActive" chain of objects in these queries. It compiles just fine and I can't see why I wouldn't be able to do this. If I change it to:

var query = session.QueryOver<LogMerges>()
    .Where(log => log.Logfile.Id == 0);

…the query goes through. However, if I try to access the other member variable:

var query = session.QueryOver<LogMerges>()
    .Where(log => log.Logfile.LastReference == DateTime.Now);

…I get a similar "could not resolve property" error message.

So if it turns out that I CANNOT do the Object chain of "log.Logfile.IsActive", what's the proper way to implement it? Do I need to perform a bunch of JOINs to do this?

Thanks in advance for any help!

Best Answer

Yes, you do need do need to join on Logfile. Nhibernate is ultimately going to turn your QueryOver query into SQL, so accessing a property on a referenced table doesn't make sense. In other words, you couldn't write the SQL:

select
    *
from
    logmerges
where
    logmerges.logfile.last_reference = ...

Obviously you'd get a syntax error here--you'd need to join to LogFile:

select
    *
from
   logmerges
   inner join logfiles on logfiles.id = logmerges.logfile_id
where 
   logfiles.last_reference = ...

And so therefore you can't write QueryOver like that either.

var query = session.QueryOver<LogMerges>()
    .JoinQueryOver(lm => lm.LogFile)
    .Where(lf => lf.LastReference == DateTime.Now)
    .List<LogMerges>();
Related Topic