A web-friendly query language that transforms into Microsoft Graph, Active Directory, and SCIM filters
Quaero is a small, intuitive query language designed to unify filtering across different systems. Instead of learning multiple query syntaxes for Microsoft Graph, LDAP, and SCIM, you write queries once in Quaero and transform them into the target system's native filter format.
Key Benefits:
- Universal syntax - Write queries once, use everywhere
- Web-friendly - Uses readable operators like
eq,gt,andinstead of symbols - Type-safe - Built for .NET with strong typing support
- Optimizable - Automatic query optimization removes redundancies
# Core library
dotnet add package Quaero
# Target-specific packages
dotnet add package Quaero.MicrosoftGraph
dotnet add package Quaero.Ldap
dotnet add package Quaero.Scimusing Quaero;
// Parse a filter from string
Filter filter = Filter.Parse("age gt 42 and department eq \"Engineering\"");
// Or build programmatically
Filter filter = Filter.And(
Filter.GreaterThan("age", 42),
Filter.Equals("department", "Engineering")
);
// Transform to target system
string microsoftGraph = filter.ToMicrosoftGraphFilter();
string ldapFilter = filter.ToLdapFilter();
string scimFilter = filter.ToScimFilter();
// Use in-memory
Func<Employee, bool> predicate = filter.ToPredicate<Employee>();| Operator | Description | Example |
|---|---|---|
eq |
Equals | name eq "John" |
ne |
Not equals | status ne "inactive" |
gt |
Greater than | age gt 21 |
ge |
Greater than or equal | salary ge 50000 |
lt |
Less than | score lt 100 |
le |
Less than or equal | rating le 5 |
sw |
Starts with | email sw "admin" |
ew |
Ends with | domain ew ".com" |
co |
Contains | title co "Manager" |
in |
In list | status in ["active", "pending"] |
pr |
Present (not null) | phoneNumber pr |
and |
Logical AND | age gt 18 and verified eq true |
or |
Logical OR | role eq "admin" or role eq "moderator" |
not |
Logical NOT | not(status eq "deleted") |
Here's how the same Quaero query translates across different systems:
| System | Query |
|---|---|
| Quaero | age gt 42 and department eq "Engineering" |
| Microsoft Graph | age gt 42 and department eq 'Engineering' |
| LDAP | (&(age>=43)(department=Engineering)) |
| SCIM | age gt 42 and department eq "Engineering" |
// Quaero query
string query = @"(department in [""Sales"", ""Marketing""] and salary ge 75000)
or (role eq ""Senior Developer"" and experience gt 5)";
Filter filter = Filter.Parse(query);
// Microsoft Graph: ((department in ('Sales', 'Marketing') and salary ge 75000) or (role eq 'Senior Developer' and experience gt 5))
// LDAP: (|((&(|(department=Sales)(department=Marketing))(salary>=75000))(&(role=Senior Developer)(experience>=6))))
// SCIM: (department in ["Sales", "Marketing"] and salary ge 75000) or (role eq "Senior Developer" and experience gt 5)Filter filter = Filter.Parse("name eq \"John\" and name eq \"John\"");
Filter optimized = filter.Optimize(); // Removes redundant conditionsrecord Employee(string Name, int Age, string Department);
var employees = new List<Employee>
{
new("Alice", 30, "Engineering"),
new("Bob", 45, "Sales"),
new("Carol", 28, "Engineering")
};
Filter filter = Filter.Parse("age gt 35 or department eq \"Engineering\"");
Func<Employee, bool> predicate = filter.ToPredicate<Employee>();
var results = employees.Where(predicate).ToList();
// Returns: Alice, Bob, Carol// Safe parsing
if (Filter.TryParse("invalid query", out Filter? filter))
{
// Success
string result = filter.ToMicrosoftGraphFilter();
}
else
{
// Handle parse error
Console.WriteLine("Invalid query syntax");
}Entity Framework Extensions and Dapper Plus are major sponsors and proud to contribute to the development of Quaero.

