Search code examples
nhibernatelinq-to-nhibernatenhibernate-criteriaqueryover

nHibernate QueryOver Inheritance


I have something like this :

    public class User
    {
       /* some properties */
       public virtual int Id { get; set; }
       public abstract string LastName { get; }

    }
    public class Student 
    {
       public virtual int Id { get; set; }
       public virtual string LastName{ get; set; }
    }

    public class StudentUser : User
    {
       public virtual Student Student { set; get; }

        public override string LastName 
        {
            get { return Student.LastName; }
        }
    }

    public class foo
    {
         public virtual int Id { get; set; }

         public virtual IList<User> Users { get; set; }
    }


 1. I would like to do the following using QueryOver :
   var query = session.QueryOver<foo>();
       User User = null;

//case 1: This is not working
       query.JoinAlias(x=> x.Users , () => User )
                 .Where(() => ((StudentUser)User).Student.LastName == "smith" );

//case 2: Also This is not working
       query.JoinAlias(x=> x.Users , () => User )
                 .Where(() => ((StudentUser)User).LastName == "smith" );

//case 3: This is working
       query.JoinAlias(x=> x.Users , () => User )
                 .Where(() => ((StudentUser)User).Id == 123 ); 

When I use query.JoinAlias(x=> x.Users , () => User ) more than one time, I get this exception An item with the same key has already been added.

Also I get this exception : could not resolve property: Student.LastName of: Entities.User in case 1 and case 2

But it is working with the Id property (case 3)

It might be look like :

SELECT        *
FROM         Foo INNER JOIN
                      Users ON Foo.Id = Users.FooId_FK INNER JOIN
                      Students ON Users.StudentId_FK = Students.Id
where Students.LastName = 'smith'

How can I get the LastName property value?


Solution

  • I think this should work:

    session.QueryOver<foo>()
        .JoinQueryOver(f => f.Users)
        .JoinQueryOver(u => ((StudentUser)u).Student)
            .Where(st => st.LastName == "smith")
    

    Or keeping with JoinAlias:

    User userAlias = null;
    Student studentAlias = null;
    
    session.QueryOver<foo>()
        .JoinAlias(f => f.Users, () => userAlias)
        .JoinAlias(() => ((StudentUser)userAlias).Student, () => studentAlias)
            .Where(() => studentAlias.LastName == "smith")