6

I have domain class location

    public abstract class BaseEntity<T> where T: struct 
    {
    public virtual T Id { get; set; }
    public virtual bool Equals(BaseEntity<T> other)
    }

    public class Location : BaseEntity<Int32>
    {

    public  User User {get;set;}
    }

    public class User : BaseEntity<Int32>
    {
    public string Name {get;set;
    }

    public OtherInfo Otherinfo {get;set;};
     }
    public class OtherInfo
    {
    public  string preference {get;set;};
    }

    var criteria = session.CreateCriteria(typeof(Location), "alias");
    criteria.CreateCriteria("User", "user", JoinType.InnerJoin);
    criteria.CreateCriteria("user.Otherinfo", "userInfo",JoinType.InnerJoin); 
    criteria.Add(Restrictions.Eq("user.Id", 100));
    criteria.SetProjection(Projections.Alias(Projections.Id(), "Id"),                            Projections.Alias(Projections.Property("user.Name"), "Name"),  Projections.Alias(Projections.Property("userInfo.preference "), "pref"));

now when i execute above criteria, it gives error on userInfo.preference. {NHibernate.QueryException: could not resolve property: Otherinfo of: Location.User What is mistake here. is it because of multi nested objects

Techmaster
  • 1,032
  • 2
  • 12
  • 26

2 Answers2

4

Use CreateAlias instead:

criteria.CreateAlias("User", "user", JoinType.InnerJoin);
criteria.CreateAlias("user.Otherinfo", "userInfo",JoinType.InnerJoin); 
Martin Ernst
  • 5,629
  • 2
  • 17
  • 14
  • it was just my typo while posting question, in code its correct. – Techmaster May 24 '12 at 14:40
  • do you have any other clue, please let me know, I am struck from very long time. – Techmaster May 24 '12 at 14:52
  • Yes sure - use CreateAlias instead of CreateCriteria - CreateCriteria will move you down the association, CreateAlias is more natural - updated the example – Martin Ernst May 24 '12 at 15:00
  • Same issue even after using CreateAlias. :( – Techmaster May 24 '12 at 15:08
  • um.. I see you're also specifying an alias in the session.CreateCriteria(typeof(Location)) - try remove the "alias" – Martin Ernst May 24 '12 at 15:12
  • tried removing that too. same issue. Is this kind of nested allowed? – Techmaster May 24 '12 at 15:19
  • Nested criteria is definitely supported by NHibernate. OtherInfo is not an entity, so I'm presuming you haven't mapped it as such - you will either have to map it using a custom type, or as an entity, or as a component of User. How have you mapped OtherInfo onto User? – Martin Ernst May 24 '12 at 15:22
3

This is for someone else looking for nested projections and nested join with NHibernate Criteria:

public class A
{
    public B {get;set;}
    public string PropertyA {get;set;}
}
public class B
{
    public C {get;set;}
}    
public class C
{
    public string CName {get;set;}
}
//you want to project and join 3 tables querying from A and get CName of C
//  InstanceA.B.C.CName

you cannot use "." dot as your alias name + you can only access 1 level deep within an alias(aliasA.PropertyA)

//you have to create 3 alias for each class/instance/table
DetachedCriteria joinNested3tables = DetachedCriteria.For<A>("aliasA") //level 1 alias
            .CreateAlias("aliasA.B", "aliasB", JoinType.InnerJoin) //level 2 alias
            .CreateAlias("aliasB.C", "aliasC", JoinType.InnerJoin) //level 3 alias
          .SetProjection(Projections.ProjectionList()
            .Add(Projections.Property("aliasC.CName"), "CNameProjection")
            //you cannot have more than 1 dot operator like below
            //.Add(Projections.Property("aliasB.C.CName"), "CNameProjection")
            );
kite
  • 1,478
  • 1
  • 15
  • 27