13

I have a problem with NHibenate. When I run queryover, I get an error "could not resolve property: User.Name of: MegaOnlineChat.Core.Entities.Message".What am I doing wrong?

Entity objects

public class EntityObject<TId>
    {
        public virtual Int32 Id { get; set; }
    }
public class User:EntityObject<Int32>
    {
        public virtual String Name { get; set; }
        public virtual String Password { get; set; }
        public virtual Boolean Admin { get; set; }
        public virtual IList<Message> Messages { get; set; }
    }
public class Message:EntityObject<Int32>
    {
        public virtual String Text { get; set; }
        public virtual User User { get; set; }
        public virtual DateTime Date{ get; set; }
    }

Mapping

public class UserMapping:ClassMap<User>
{
    public UserMapping()
    {
        Table("Users");
        Id(m => m.Id).GeneratedBy.Native();
        Map(m => m.Name).Unique().Not.Nullable();
        Map(m => m.Admin).Not.Nullable();
        Map(m => m.Password).Not.Nullable();

        HasMany(m => m.Messages).KeyColumn("User_id");
    }
}
public class MessageMapping:ClassMap<Message>
{
    public MessageMapping()
    {
        Table("Messages");

        Id(m => m.Id).GeneratedBy.Native();

        Map(m => m.Text).Not.Nullable();
        Map(m => m.Date).Not.Nullable();

        References(m => m.User, "User_id").Not.Nullable();
    }
}

QueryOver

NHibernateSession.QueryOver<Message>().Where(x => x.User.Name == name).List<Message>().Last();
KyorCode
  • 1,477
  • 1
  • 22
  • 32
valik
  • 171
  • 1
  • 1
  • 9

1 Answers1

18

QueryOver is not the same as the Linq query provider. It would be easier to do:

NHibernateSession.Query<Message>().Where(x => x.User.Name == name).ToList();

But if you want to use QueryOver, you will need to explicitly join the relationships you want to navigate:

NHibernateSession.QueryOver<Message>()
    .JoinQueryOver(x => x.User) // navigate to the user on the relationship
    .Where(u => u.Name == name) // this restriction is on the User now
    .List();

you could also do this using an alias for user

Martin Ernst
  • 5,629
  • 2
  • 17
  • 14
  • Is there a way to do this if you want to have additional `.Where()` clauses on `Message`? – Mike Christensen Jan 24 '14 at 02:38
  • If you're using the Linq provider, you can do something like: session.Query().Where(x => ...).Where(x => ..) etc.. - it will combine the Where's into 1 conjunction (AND) when it issues the query, if you're using QueryOver, you can use the .And(..) method – Martin Ernst Jan 24 '14 at 09:34
  • Ah, I figured it out. I was looking for [.JoinAlias](http://stackoverflow.com/questions/21322363/nhibernate-cannot-resolve-property-of-one-to-one-mapping-when-used-in-a-filter/21323504#21323504) – Mike Christensen Jan 24 '14 at 16:17