Fluent NHibernate - NHibernate.QueryException: could not resolve property
Asked Answered
R

1

6

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!

Ringside answered 17/10, 2014 at 23:57 Comment(0)
C
8

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>();
Chainsmoke answered 18/10, 2014 at 1:27 Comment(1)
Thanks so much, Andrew, for the quick response! It worked perfectly! I'm not particularly strong in SQL and I always get confused with Joins, so I am very thankful for the help!Ringside

© 2022 - 2024 — McMap. All rights reserved.