Search code examples
nhibernatequeryover

NHibernate JoinQueryOver on linkin Property in the other class


To put it simple I have these 3 classes

class Bag { int Id; }

class Candy { int Id; }

class CandyBag
{
    int Id;
    Candy candy;
    Bag bag;
}

I need to list all Bags that contains certain type of Candy, Im THINK it goes something like this:

session.QueryOver<Bag>(() => bagAlias)
    .JoinQueryOver<CandyBag>()
        .Where(candyBag => candgyBag.Bag.Id == bagAlias.Id)
        .And(candyBag => candgBag.Candy.Id == userSelectedCandy.Id)
    .List();  

The thing is, I can't have a property of CandyBag nor Candy in the Bag class, because I have more items that a bag can hold (like Cloth/ClotheBag Food/FoodBag). And I'm saying this because I can't do

session.QueryOver<Bag>(() => bagAlias)
    .JoinQueryOver<CandyBag>(bag => bag.CandyBag, () => candyBagAlias)
        .Where(candyBag => candyBag.Bag.Id == bagAlias.Id)
    .List();  

Thanks in advance.


Solution

  • Based on your example I've created this classes:

    public class Bag { 
        public int Id {get; set;} 
    }
    public class Candy {
        public int Id { get; set; } 
    }
    public class CandyBag
    {
        public int Id { get; set; }
        public Candy Candy { get; set; }
        public Bag Bag { get; set; } 
    }
    

    and this NHibernate mappings

     <class name="Bag" table="Bag" lazy="false" >
            <id name="Id">
                <generator class="identity" />
            </id>
            <!--<property name="CreationDate" />-->
        </class>
        <class name="Candy" table="Candy" lazy="false" >
            <id name="Id">
                <generator class="identity" />
            </id>
            <!--<property name="CreationDate" />-->
        </class>
        <class name="CandyBag" table="CandyBag" lazy="false" >
            <id name="Id">
                <generator class="identity" />
            </id>
            <many-to-one name="Candy" column="CandyId" lazy="false" />
            <many-to-one name="Bag" column="BagId" lazy="false" />
        </class>
    

    To obtain Bag collection of a certain Candy:

    IList<Bag> bags = null;
    using (var session = OpenSession())
    {
        CandyBag candyBagAlias = null;
        bags = session.QueryOver<CandyBag>(() => candyBagAlias)     
            .Where(() => candyBagAlias.Candy.Id == userSelectedCandyId )
            .List()
            .Select(cb => cb.Bag).ToList();
    
        // or with LINQ
        bags = (
            from bag in session.Query<Bag>()
            join candyBag in session.Query<CandyBag>() on bag equals candyBag.Bag
            where candyBag.Candy.Id == userSelectedCandyId 
            select bag 
        ).ToList();
    }
    return bags;
    

    I prefer the LINQ way because it is really simple to understand.