简体   繁体   中英

Nhibernate Disjunction (“OR”) Query Across Many-To-One and Many-To-Many Relationships

This question is close to but not the same as the one here: NHibernate Query across multiple tables

Basically, my question is given the following model, how would I query to find out if the current dog has the name "foo" or a past dog has the name "foo" (disjunction). Essentially I have a Many-To-One relationship for CurrentDog and a Many-To-Many relationship for PastDogs.

public class Dog {
    public string name {get; set;}
}

public class Owner {
    public string firstname {get; set;}
    public string lastname {get; set;}
    public Dog CurrentDog {get; set;}
    public Dog[] PastDogs {get; set;}
}

I'd guess the SQL should look something like this:

    SELECT o.* FROM owners AS o
    INNER JOIN dogs AS cd ON o.current_dog_id = cd.id
    INNER JOIN owner_past_dog_maps AS pd ON o.id = pd.owner_id
    INNER JOIN dogs AS d ON pd.dog_id = d.id
    WHERE d.name = 'foo' 
    OR cd.name = 'foo'

Hope that makes sense... I'll try clarify it if anyone asks.

I've try to solve it using QueryOver and alias

Owner myOwner = null;
Dog myCurrentDog = null; 
Dog myPastDogs = null;

var sax = _HibSession.QueryOver<Owner>(() => myOwner)
                .JoinAlias(() => myOwner.CurrentDog, () => myCurrentDog, JoinType.InnerJoin)
                .JoinAlias(() => myOwner.PastDogs, () => myPastDogs , JoinType.InnerJoin)
                .Where(Restrictions.Disjunction()
                    .Add(Restrictions.EqProperty(myCurrentDog.Name,"foo"))
                    .Add(Restrictions.EqProperty(myPastDogs.Name,"foo"))                    
                )                                            
                .List<Owner>();

I hope it's helpful!

I guess I should have started off that I was new to NHibernate. What I didn't understand was the aliasing going on in NHibernate and that you're creating aliases not for the tables but for the relationships and the property names. Behold, the solution that will return all the owners who have or had a dog name foo:

    var output = Session.CreateCriteria<Owner>()
        .CreateAlias("CurrentDog", "cd")
        .CreateAlias("PastDogs", "pd")
        .Add
        (
            Restrictions.Disjunction()
            .Add(Restrictions.Eq("cd.Name", "foo"))
            .Add(Restrictions.Eq("pd.Name", "foo"))
        )
        .List<Owner>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM