Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
964 views
in Technique[技术] by (71.8m points)

asp.net mvc - 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();

Any help is much appreciated thx!

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();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

  • Restrictions.Or(restriction1, restriction1)
  • Restrictions.Disjunction().Add(restriction1).Add(restriction2).Add(...

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))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...