Question

I have 3 variables in my filter: int? Owner, int? Watcher, int? CreatedBy.

Now, depending of what is entered in filter (if CreatedBy.HasValue etc), i want to combine my query in NHibernate with OR statements. So far I have

if (filter.Owner.HasValue)
{
    criteria.Add(Expression.Disjunction()
            .Add(Restrictions.Eq("ou.User.Id", filter.Owner.Value))
            .Add(Restrictions.Eq("ou.Status", 0)));
}

if (filter.Watcher.HasValue)
{
    criteria.Add(Expression.Disjunction()
            .Add(Restrictions.Eq("ou.User.Id", filter.Watcher.Value))
            .Add(Restrictions.Eq("ou.Status", 1)));
}

if (filter.CreatedBy.HasValue)
{
    criteria.Add(Restrictions.Eq("u.Id", filter.CreatedBy));
}

before, I added createAlias etc... But, how to combine those 3 queryies in one query with OR according to variables entered in filter?

Was it helpful?

Solution

I'd say, that the first part (you already have) is ok and also the second would be very straightforward. The way how to process that could be:

// this would be the collector of criteria
var restrictions = new List<ICriterion>();

if (filter.Owner.HasValue)
{
    restrcitons.Add(Expression.Disjunction()
        .Add(Restrictions.Eq("ou.User.Id", filter.Owner.Value))
        .Add(Restrictions.Eq("ou.Status", 0))
    );
}

if (filter.Watcher.HasValue)
{
    restricitons.Add(Expression.Disjunction()
            .Add(Restrictions.Eq("ou.User.Id", filter.Watcher.Value))
            .Add(Restrictions.Eq("ou.Status", 1))
    );
}

if (filter.CreatedBy.HasValue)
{
    restrictions.Add(Restrictions.Eq("u.Id", filter.CreatedBy));
}

// now we can inject the result of the above code into 
// Disjunction or Conjunction...
if(restrictions.Count > 0)
{
    var disjunction = Restrictions.Disjunction();
    restrictions .ForEach(r => disjunction.Add(r));
    criteria.Add(disjunction)
}

Also, I would CreateAlias somewhere inside of the if - close to decision if the JOIN will be required or not (based on search parameters). Unless you are checking that elsewhere.

And maybe try to move the if into methods. They can take restrictions and criteria and decide how to handle them. it would be like this

RestrictOwner  (filter, restrictions, criteria);
RestrictWatcher(filter, restrictions, criteria);
RestrictCreator(filter, restrictions, criteria);

if(restrictions.Count ...

And later, they could be maybe even more generic...

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