asp.net-mvcnhibernatequeryover

NHibernate QueryOver with WhereRestriction as OR


I have this query but I can't seem to find how I set my WhereRestrictionOn as an OR. Now they function as AND but I want one OR the other.

var privateInfo = Session.QueryOver<ConContact>()
            .JoinAlias(c => c.PrivateInfos, () => pi)
            .WhereRestrictionOn(c => c.FirstName).IsLike(_selectedFirstLetter + "%")
            .WhereRestrictionOn(c => c.LastName).IsLike(_selectedFirstLetter + "%") // todo: change to firstname OR lastname
            .Where(c => c.Status == ContactStatus.Approved)
            .Select(
                Projections.Property("pi.Id").WithAlias(() => sri.Id),
                Projections.Property("FirstName").WithAlias(() => sri.Name), //todo: get fullname here => Add concontact object in privateinfo
                Projections.Property("pi.Address").WithAlias(() => sri.Address),
                Projections.Constant("Contact").WithAlias(() => sri.Type)
            )
            .TransformUsing(Transformers.AliasToBean<SearchResultInfo>())
            .List<SearchResultInfo>()
            .ToList();

SOLUTION:

var privateInfo = Session.QueryOver<ConContact>()
            .JoinAlias(c => c.PrivateInfos, () => pi)
            .Where(
                Restrictions.Disjunction()
                    .Add(Restrictions.Like("FirstName", _selectedFirstLetter + "%"))
                    .Add(Restrictions.Like("LastName", _selectedFirstLetter + "%"))
            )
            .Where(c => c.Status == ContactStatus.Approved)
            .Select(
                Projections.Property("pi.Id").WithAlias(() => sri.Id),
                Projections.Property("FirstName").WithAlias(() => sri.Name), //todo: get fullname here => Add concontact object in privateinfo
                Projections.Property("pi.Address").WithAlias(() => sri.Address),
                Projections.Constant(NewObjectType.Contact).WithAlias(() => sri.Type)
            )
            .TransformUsing(Transformers.AliasToBean<SearchResultInfo>())
            .List<SearchResultInfo>()
            .ToList();

Solution

  • The top level .Where() family (including WhereRestrictionOn) is always joined with AND. So we have to explicitly use something like:

    So, this could be our case:

    .Where(
        Restrictions.Disjunction()
            .Add(Restrictions.On<ConContact>(c => c.FirstName)
                                  .IsLike(_selectedFirstLetter, MatchMode.Start))
            .Add(Restrictions.On<ConContact>(c => c.LastName)
                                  .IsLike(_selectedFirstLetter, MatchMode.Start))
            // more OR ...
            //.Add(Restrictions.On<ConContact>(c => c.MiddleName)
            //                      .IsLike(_selectedFirstLetter, MatchMode.Start))
    )
    

    As discussed here: 16.2. Simple Expressions, for simple stuff we can even use || (cited small example):

    .Where(p => p.Name == "test name" && (p.Age > 21 || p.HasCar))