Question

public class PostUser
    {
        int UserId {get;set;}
        string Username {get;set;}
        string Email {get;set;}
        IList<Post> Posts {get;set;}
    }

   public class Post
   {
        int PostId {get;set;}
        int ThreadId {get;set;}
        int UserId {get;set;}
        string PageText {get;set;}
        string IPAddress {get;set;}
        PostUser Userposted {get;set;}
   }

I want to make a query as below:

Select * from POST JOIN POSTUSER ON POST.USERID = POSTUSER.USERID
WHERE POST.IPADDRESS LIKE '%86%' OR POST.PAGETEXT like '%something%' 
OR POSTUSER.EMAIL LIKE '%BLA%'

My attempt was to create two disjunctions:

Disjunction postuserdisjunction = new Disjunction();
Disjunction postdisjunction = new Disjunction();

postuserdisjunction.Add(Restrictions.Like("email","%bla%"))
postdisjunction.Add(Restrictions.Like("IPAddress","%86%"))

IList<Post> p = _session.CreateCriteria<Post>()
                        .Add(postdisjunction)
                        .CreateCriteria("UserPosted")
                        .Add(postuserdisjunction)
                        .List<Post>();

But this is giving me result SQL as below:

Select * from POST JOIN POSTUSER ON POST.USERID = POSTUSER.USERID
    WHERE (POST.IPADDRESS LIKE '%86%' OR POST.PAGETEXT like '%something%' ) AND POSTUSER.EMAIL LIKE '%BLA%'

Please help!

Was it helpful?

Solution

What we can do here is to use alias for each table, and use OR expression for both disjunctions:

Disjunction postuserdisjunction = new Disjunction();
Disjunction postdisjunction = new Disjunction();

postuserdisjunction.Add(Restrictions.Like("up.email","%bla%"))  // alias "up" see below
postdisjunction.Add(Restrictions.Like("p.IPAddress","%86%"))    // alias "p"

IList<Post> p = _session.CreateCriteria<Post>("p")      // alias is "p" as above..
                    //.Add(postdisjunction)             // will use it later, not here
                    .CreateCriteria("UserPosted", "up") // alias is "up"
                    // here we can use both disjunctions with OR                   
                    .Add(
                       Restrictions.Or(
                          postdisjunction
                        , postuserdisjunction
                       )
                    )
                    .List<Post>();

EDIT: In case, that we do not need two Disjunctions... we can just use one, with aliases

Disjunction disjunction = new Disjunction();

disjunction.Add(Restrictions.Like("up.email","%bla%"))    // alias "up" see below
disjunction.Add(Restrictions.Like("p.IPAddress","%86%"))  // alias "p"

IList<Post> p = _session.CreateCriteria<Post>("p")      // alias is "p" as above..
                    .CreateCriteria("UserPosted", "up") // alias is "up"
                    // here we add just one set of OR
                    .Add(disjunction)
                    .List<Post>();

This is even more simple and clear, but only if both disjunctions are not needed, and we use the alias

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top