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