There are multiple ways to do it, I used mix of criteria API and query objects.
For example if you have Persons collection which you want to query:
1) The more flexible way criteria API: GetPerson(IList query)
public class Criteria
{
Object Property; // (Domain property, not DB)// (String Or Lambda) Age, Father.Age, Friends, etc
Object Operator; //(Enum or String)(Eq, Gr, Between,Contains, StartWith, Whatever...)
Object Value; // (most likely Object, or use generics Criteria<T>), (Guid, int[], Person, any type).
}
2) Strongly described query object:
public class PersonQuery
{
Guid? Id;
GenderEnum? Gender;
Int32? Age;
Int32? AgeMin;
Int32? AgeMax;
String Name;
String NameContains;
Person FatherIs;
Person MotherIs;
//...
}
Use Nullable<> for Value types and assign Null to indicate that parameter is not required.
Each method has positive and negative sides.