How to join multiple MethodCallExpressions into one Expression? - c#

I have a query and I need to apply n filters to it. However I have to use expressions. So far I have expression constructed for each filter, which works pretty good. Issue is I want to join these filters into one expression so I could use it as parameter for LINQ's .Where().
Filter code:
//Filters could slightly differ in functionality
private Expression<Func<T, bool>> StringPropertyContains<T>(Filter filter)
{
if (filter == null)
{
throw new ArgumentNullException(nameof(filter));
}
if (typeof(T).GetProperties().FirstOrDefault(pi => pi.Name.Equals(filter.PropertyName, StringComparison.OrdinalIgnoreCase)) == null)
{
throw new ArgumentNullException($"Type {typeof(T)} does not contain property {filter.PropertyName}");
}
var propertyInfo = typeof(T).GetProperty(filter.PropertyName);
var param = Expression.Parameter(typeof(T));
var member = Expression.MakeMemberAccess(param, propertyInfo);
var constant = Expression.Constant(filter.Value, typeof(filter.Type));
var methodInfo = typeof(filter.Type).GetMethod(filter.Method, new Type[] { typeof(filter.Type) });
var body = Expression.Call(member, methodInfo, constant);
return Expression.Lambda<Func<T, bool>>(body, param);
}
private Expression<Func<T, bool>> Filter<T>(T t)
{
//TODO join filters while each filter should have its different parameter
//the parameter is currently constructed in the object and is accessible via property Filter[] ParsedFilter
}
Filter class:
internal class Filter
{
public string Type { get; }
public string Method { get; }
public string PropertyName { get; }
public string Value { get; }
}
Desired usage:
IQueryable<T> q = query.Where(this.Filter)
To be honest I have pretty bad headache with this issue because I am pretty new to expressions. So thanks in regards for any help.

You can not pass a class as argument to a Where clause however you can use Linq Expressions to acheive what you want:
Expression<Func<T, bool>> filter = q => q.type == filter.Type && q.Value == filter.Value;
var x = query.Where(filter);

Related

How do I overload LINQ string.Contains()?

For a generic filter I am implementing, I need to modify the following to accept the column name which will be searched in the Where method, something like:
public IQueryable<TEntity> GetEntities(string val)
{
TEntity entity = _DbContext.Set<TEntity>()
.Where(e => e.Col1.Contains(val));
return entities;
}
to be changed to
public IQueryable<TEntity> GetEntities(string val, string colName)
{
TEntity entity = _DbContext.Set<TEntity>()
.WhereContains(val, colName);
return entities;
}
colName is the name of a string column.
I looked at https://blog.jeremylikness.com/blog/dynamically-build-linq-expressions/ but could not modify the example there for my needs. The answer should be in the form of
public static IQueryable<TEntity> WhereContains<TEntity>(this IQueryable<TEntity> query, string value, string colName)
where TEntity : class
{
...
...
}
But I cant make it work...
OK, found a good reference and was able to modify it:
public static IQueryable<T> TextFilter<T>(IQueryable<T> source, string[] colNames, string[] terms)
{
if (colNames.Length == 0) return source;
// T is a compile-time placeholder for the element type of the query.
Type elementType = typeof(T);
// Get all the properties on this specific type for colNames.
List<PropertyInfo> props = new List<PropertyInfo>();
for (int i = 0; i < colNames.Length; i++)
{
PropertyInfo prop = elementType.GetProperties().Where(x => x.PropertyType == typeof(string) && x.Name.ToLower() == colNames[i].ToLower()).FirstOrDefault();
if (prop == null) { return source; }
props.Add(prop);
}
// Get the right overload of String.Contains. Can be replaced e.g. with "Contains"
MethodInfo containsMethod = typeof(string).GetMethod("StartsWith", new[] { typeof(string) })!;
// Create a parameter for the expression tree:
// the 'x' in 'x => x.PropertyName.Contains("term")'
// The type of this parameter is the query's element type
ParameterExpression prm = Expression.Parameter(elementType);
// Map each property to an expression tree node
List<Expression> expressions = new List<Expression>();
for (int i = 0; i < colNames.Length; i++)
{
expressions.Add(
Expression.Call(
Expression.Property(
prm,
props.ElementAt(i)
),
containsMethod,
Expression.Constant(terms[i])
)
);
}
// Combine all the resultant expression nodes using ||
Expression body = expressions
.Aggregate(
(prev, current) => Expression.And(prev, current)
);
// Wrap the expression body in a compile-time-typed lambda expression
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(body, prm);
// Because the lambda is compile-time-typed (albeit with a generic parameter), we can use it with the Where method
return source.Where(lambda);
}
I was not able to make this work as an extension, so calling it is done with:
var qry= QueryableExtensions.TextFilter(_crudApiDbContext.Set<TEntity>()
.Where(entity => entity.someColumn==someValue),
filters.Keys.ToArray(), filters.Values.ToArray());
List<TEntity> entities = await qry
.Skip(pageSize * (page - 1)).Take(pageSize).ToListAsync();

Filter IQueryable which contains (%like%) any of the items in the List<string>

I want to filter an IQueryable/List using List without hitting the database. The IQueryable result should include all result containing any of the strings in the List and the length of the list is unspecified.
myQueryable = myQueryable.Where(filelist => filelist.Location.Contains(filterList[0]) || filelist.Location.Contains(filterList[1]) || filelist.Location.Contains(filterList[N])...);
I'm using ASP.NET Core 3 and will use the IQueryable to hit the databse in a later phase using Entity Framework.
I've tried these two codes which did not work and my IQuery works fine if i exclude my trial codes (for filtering the attribute, location).
workOrders = workOrders.Where(filelist => filterList.Contains(filelist.Location)); //Returns only exact match
workOrders = workOrders.Where(filelist => filterList.Any(filter => filelist.Location.ToUpperInvariant().Contains(filter.ToUpperInvariant()))); //Returns error
Expression<Func<Workorder, bool>> predicate = filelist => false;
foreach (var filter in filterList)
{
Expression<Func<Workorder, bool>> orPredicate = filelist =>
filter.Contains(filelist.Location);
var body = Expression.Or(predicate.Body, orPredicate.Body);
predicate = Expression.Lambda<Func<Workorder, bool>>(body,
predicate.Parameters[0]);
}
workOrders = workOrders.Where(predicate); //Returns Error
class Workorder //Database Model
{
public string SiteId { get; set; }
public string Location { get; set; }
}
List<string> filterList //List to be used as filter
{
"filterOne",
"filterTwo",
"filterN"
};
The second code i ran gives me an error which i can get nothing out of.
System.InvalidOperationException: When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.
Third code i ran gives me this error,
System.InvalidOperationException: Operation is not valid due to the current state of the object.
at Microsoft.EntityFrameworkCore.Relational.Query.Pipeline.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
I have definitely not tested this... but I don't think you can do it in a one-liner if you pretend EF to parse it afterwards.
However, something like this should be fine:
Expression<Func<WorkOrder, bool>> predicate = filelist => false;
foreach(var filter in filterList) {
Expression<Func<WorkOrder, bool>> orPredicate = filelist => filter.Contains(filelist.Location);
var body = Expression.Or(predicate.Body, orPredicate.Body);
predicate = Expression.Lambda<Func<WorkOrder,bool>>(body, predicate.Parameters[0]);
}
And then:
myQueryable = myQueryable.Where(predicate);
We are basically just telling it:
.Where(filelist => false || filterList[0].Contains(filelist.Location) || filterList[1].Contains(filelist.Location) || ...);
Edit
Still untested on EF, but at least the syntax seems to be ok: https://dotnetfiddle.net/Htr7Zr
It took me a while but i used your example to construct an expression tree that worked.
List<filterList> filterList //List to be used as filter
{
"filterOne",
"filterTwo",
"filterN"
}
class Workorder //Database Model
{
public string SiteId { get; set; }
public string Location { get; set; }
}
static Expression<Func<T, bool>> GetExpression<T>(string propertyName, List<string> propertyValue)
{
Expression orExpression = null;
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
foreach (string searchTerm in propertyValue)
{
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(searchTerm, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
if(orExpression == null) //to handle intial phase when left expression = null
{
orExpression = Expression.Call(propertyExp, method, someValue);
}else
{
orExpression = Expression.Or(orExpression, containsMethodExp);
}
return Expression.Lambda<Func<T, bool>>(orExpression, parameterExp);
}
myQueryable = myQueryable.Where(GetExpression<Workorder>(property, filterList));
This Equals:
myQueryable = myQueryable.Where(filelist => filelist.Location.Contains(filterList[0]) || filelist.Location.Contains(filterList[1]) || filelist.Location.Contains(filterList[N])...);

LINQ Filter Implementation with Expressions

In MVC4 , I am providing Search box to the user to search any value in Table.
So I am implementing Generic Filter Condition at server side in C#
Need a help to combine multiple expressions to form single expression
Expression<Func<T, bool>>
For Example
Table Columns
MenuText, Role Name (Role.Name mapping), ActionName
Now If user entered in search box for ABC , which can be in any of the rows in shown columns, need to filter.
Model
public class Menu
{
public string MenuText {get;set;}
public Role Role {get;set;}
public string ActionName {get;set;}
}
public class Role
{
public string Name {get;set;}
}
So far I have implemented
/// <summary>
/// string[] properties property.Name (MenuText, ActionName), including deeper Mapping names such as (Role.Name)
/// </summary>
public static Expression<Func<T, bool>> FilterKey<T>(string filterText, params string[] properties)
{
ParameterExpression parameter = Expression.Parameter(typeof (T));
Expression[] propertyExpressions = properties.Select(
x => !string.IsNullOrEmpty(x) ? GetDeepPropertyExpression(parameter, x) : null).ToArray();
Expression<Func<T, bool>> predicate = PredicateBuilder.False<T>();
foreach (Expression expression in propertyExpressions)
{
var toLower = Expression.Call(expression, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
var like = Expression.Call(toLower, typeof(string).GetMethod("Contains"), Expression.Constant(filterText.ToLower()));
//TODO: Combine expressions to form single Expression<Func<T, bool>> expression
}
return predicate;
}
/// <summary>
/// To Get Deeper Properties such as Role.Name Expressions
/// </summary>
private static Expression GetDeepPropertyExpression(Expression initialInstance, string property)
{
Expression result = null;
foreach (string propertyName in property.Split('.'))
{
Expression instance = result ?? initialInstance;
result = Expression.Property(instance, propertyName);
}
return result;
}
I have created a few search IQueryable extension methods that you should be able to use
Full blog post is here:
http://jnye.co/Posts/6/c%23-generic-search-extension-method-for-iqueryable
GitHub project is here (has a couple of extra extensions for OR searches:
https://github.com/ninjanye/SearchExtensions
public static class QueryableExtensions
{
public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, string searchTerm)
{
if (String.IsNullOrEmpty(searchTerm))
{
return source;
}
// The below represents the following lamda:
// source.Where(x => x.[property] != null
// && x.[property].Contains(searchTerm))
//Create expression to represent x.[property] != null
var isNotNullExpression = Expression.NotEqual(stringProperty.Body, Expression.Constant(null));
//Create expression to represent x.[property].Contains(searchTerm)
var searchTermExpression = Expression.Constant(searchTerm);
var checkContainsExpression = Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);
//Join not null and contains expressions
var notNullAndContainsExpression = Expression.AndAlso(isNotNullExpression, checkContainsExpression);
var methodCallExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { source.ElementType },
source.Expression,
Expression.Lambda<Func<T, bool>>(notNullAndContainsExpression, stringProperty.Parameters));
return source.Provider.CreateQuery<T>(methodCallExpression);
}
}
This allows you to write something like:
string searchTerm = "test";
var results = context.Menu.Search(menu => menu.MenuText, searchTerm).ToList();
//OR for Role name
string searchTerm = "test";
var results = context.Menu.Search(menu => menu.Role.Name, searchTerm).ToList();
You might also find the following posts useful:
Search extension method that allows search accros multiple properties:
http://jnye.co/Posts/7/generic-iqueryable-or-search-on-multiple-properties-using-expression-trees
Search extension method that allows multiple or search terms on a property:
http://jnye.co/Posts/8/generic-iqueryable-or-search-for-multiple-search-terms-using-expression-trees
Thanks to NinjaNye , I have borrowed BuildOrExpression which resolved my problem
Here is the solution
public static Expression<Func<T, bool>> FilterKey<T>(string filterText, params string[] properties)
{
ParameterExpression parameter = Expression.Parameter(typeof (T));
Expression[] propertyExpressions = properties.Select(
x => !string.IsNullOrEmpty(x) ? GetDeepPropertyExpression(parameter, x) : null).ToArray();
Expression like= propertyExpressions.Select(expression => Expression.Call(expression, typeof (string).GetMethod("ToLower", Type.EmptyTypes))).Select(toLower => Expression.Call(toLower, typeof (string).GetMethod("Contains"), Expression.Constant(filterText.ToLower()))).Aggregate<MethodCallExpression, Expression>(null, (current, ex) => BuildOrExpression(current, ex));
return Expression.Lambda<Func<T, bool>>(like, parameter);
}
private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)
{
if (existingExpression == null)
{
return expressionToAdd;
}
//Build 'OR' expression for each property
return Expression.OrElse(existingExpression, expressionToAdd);
}
private static Expression GetDeepPropertyExpression(Expression initialInstance, string property)
{
Expression result = null;
foreach (string propertyName in property.Split('.'))
{
Expression instance = result ?? initialInstance;
result = Expression.Property(instance, propertyName);
}
return result;
}

LINQ (.Contains()) query against whole DbSet

public List<DbSet> Get(String q = null)
{
List<DbSet> objs = new List<DbSet>();
if (!string.IsNullOrEmpty(q) && q != "undefined")
{
objs = from dealer in db.Dealers
where dealer.Contains
......(?????)
}
}
I have some 4 DbSets in my dbcontext class. I am able to run a search like this
objs = from dealer in db.Dealers
where dealer.Name.Contains(q)
However I want to be able to do something similar except do the search against all the fields in dealer, and not just name. All the fields are strings
EDIT
Okay so I am starting to think this is not the best way to do what I'm trying to achieve. I'm looking into something called "Full Text Search". Can someone either explain to me how this works in entity or give me a link to a good resource
You could write a linq extension method:
Checkout my blog post.
http://jnye.co/Posts/7/generic-iqueryable-or-search-on-multiple-properties-using-expression-trees
(classes are also in github: https://github.com/ninjanye/SearchExtensions)
public static IQueryable<T> Search<T>(this IQueryable<T> source, string searchTerm, params Expression<Func<T, string>>[] stringProperties)
{
if (String.IsNullOrEmpty(searchTerm))
{
return source;
}
var searchTermExpression = Expression.Constant(searchTerm);
//Variable to hold merged 'OR' expression
Expression orExpression = null;
//Retrieve first parameter to use accross all expressions
var singleParameter = stringProperties[0].Parameters.Single();
//Build a contains expression for each property
foreach (var stringProperty in stringProperties)
{
//Syncronise single parameter accross each property
var swappedParamExpression = SwapExpressionVisitor.Swap(stringProperty, stringProperty.Parameters.Single(), singleParameter);
//Build expression to represent x.[propertyX].Contains(searchTerm)
var containsExpression = BuildContainsExpression(swappedParamExpression, searchTermExpression);
orExpression = BuildOrExpression(orExpression, containsExpression);
}
var completeExpression = Expression.Lambda<Func<T, bool>>(orExpression, singleParameter);
return source.Where(completeExpression);
}
private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)
{
if (existingExpression == null)
{
return expressionToAdd;
}
//Build 'OR' expression for each property
return Expression.OrElse(existingExpression, expressionToAdd);
}
private static MethodCallExpression BuildContainsExpression<T>(Expression<Func<T, string>> stringProperty, ConstantExpression searchTermExpression)
{
return Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);
}
You will also need this class:
//Create SwapVisitor to merge the parameters from each property expression into one
public class SwapVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
public static Expression Swap(Expression body, Expression from, Expression to)
{
return new SwapVisitor(from, to).Visit(body);
}
}
You can then write something like:
db.Dealers.Search(q, x => x.Field1,
x => x.Field2,
...
x => x.Field20)
Sorry, no short cuts here:
objs = from dealer in db.Dealers
where dealer.Name.Contains(q) ||
dealer.Field2.Contains(q) ||
...
dealer.Field20.Contains(q)
select dealer;
You have to specify which fields you are going to search the value in.
You can manually write conditions for all fields:
objs = from dealer in db.Dealers
where dealer.Name.Contains(q) ||
dealer.Foo.Contains(q) ||
// etc
dealer.Bar.Contains(q)
select dealer;
There is no simple way to tell Entity Framework to check all properties of entity for some condition.

Add the where clause dynamically in Entity Framework

I have this sql statement
SELECT userID from users WHERE
(name='name1' AND username='username1') OR
(name='name2' AND username='username2') OR
(name='name3' AND username='username3') OR
..........
(name='nameN' AND username='usernameN')
How can I implement this statement with entity framework using LINQ?
You can use a beautiful thing called PredicateBuilder. Use it like this
var pr = PredicateBuilder.False<User>();
foreach (var name in names)
{
pr = pr.Or(x => x.Name == name && x.Username == name);
}
return query.AsExpandable().Where(pr);
Expression<Func<User, bool>> whereExpression = null;
foreach (var name in names)
{
Expression<Func<User, bool>> e1 = u => u.Name == name;
Expression<Func<User, bool>> andExpression = e1.And(u => u.Username == name);
whereExpression = whereExpression == null
? andExpression
: whereExpression.Or(andExpression);
}
return query.Where(whereExpression);
This helper may help you.
public static class ExpressionExtensions
{
public static Expression<Func<T, bool>> And<T>(
this Expression<Func<T, bool>> leftExpression,
Expression<Func<T, bool>> rightExpression)
{
if (leftExpression == null) return rightExpression;
if (rightExpression == null) return leftExpression;
var paramExpr = Expression.Parameter(typeof(T));
var exprBody = Expression.And(leftExpression.Body, rightExpression.Body);
exprBody = (BinaryExpression)new ParameterReplacer(paramExpr)
.Visit(exprBody);
return Expression.Lambda<Func<T, bool>>(exprBody, paramExpr);
}
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> leftExpression,
Expression<Func<T, bool>> rightExpression)
{
if (leftExpression == null) return rightExpression;
if (rightExpression == null) return leftExpression;
var paramExpr = Expression.Parameter(typeof(T));
var exprBody = Expression.Or(leftExpression.Body, rightExpression.Body);
exprBody = (BinaryExpression)new ParameterReplacer(paramExpr)
.Visit(exprBody);
return Expression.Lambda<Func<T, bool>>(exprBody, paramExpr);
}
}
and:
class ParameterReplacer : ExpressionVisitor
{
private readonly ParameterExpression _parameter;
protected override Expression VisitParameter(ParameterExpression node)
{
return base.VisitParameter(_parameter);
}
internal ParameterReplacer(ParameterExpression parameter)
{
_parameter = parameter;
}
}
NOTE: this is modified from something I have so it might not work out of the box. But it would be a good starting point.
public static IQueryable<TEntity> Where<TEntity>(
this IQueryable<TEntity> source,
IEnumerable<WhereSpecifier> orClauses) where TEntity : class
{
if (!orClauses.Any()) return source.Where(t => false);
Type type = typeof (TEntity);
ParameterExpression parameter = null;
Expression predicate = Expression.Constant(false, typeof (bool));
ParameterExpression whereEnt = Expression.Parameter(type, "WhereEnt");
foreach (WhereSpecifier orClause in orClauses)
{
Expression selector;
if (orClause.Selector != null) {
selector = orClause.Selector;
parameter = orClause.Parameter;
}
else
{
parameter = whereEnt;
Type selectorResultType;
selector = GenerateSelector<TEntity>(parameter, orClause.Column,
out selectorResultType);
}
Expression clause = selector.CallMethod(orClause.Method,
MakeConstant(selector.Type, orClause.Value), orClause.Modifiers);
predicate = Expression.Or(predicate, clause);
}
var lambda = Expression.Lambda(predicate, whereEnt);
var resultExp = Expression.Call(typeof (Queryable), "Where", new[] {type},
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<TEntity>(resultExp);
}
GenerateSelector:
public static Expression GenerateSelector<TEntity>(
ParameterExpression parameter, string propertyName,
out Type resultType) where TEntity : class
{
// create the selector part, but support child properties
PropertyInfo property;
Expression propertyAccess;
if (propertyName.Contains('.'))
{
// support to be sorted on child fields.
String[] childProperties = propertyName.Split('.');
property = typeof (TEntity).GetProperty(childProperties[0]);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
for (int i = 1; i < childProperties.Length; i++)
{
property = property.PropertyType.GetProperty(childProperties[i]);
propertyAccess = Expression
.MakeMemberAccess(propertyAccess, property);
}
}
else
{
property = typeof (TEntity).GetProperty(propertyName);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
}
resultType = property.PropertyType;
return propertyAccess;
}
WHereSpecifier:
public class WhereSpecifier
{
public WhereSpecifier(string column, CheckMethod method, string value,
CheckMethodModifiers modifiers)
{
Modifiers = modifiers;
Value = value;
Column = column;
Method = method;
}
public WhereSpecifier(string column, CheckMethod method, string value)
: this(column, method, value, CheckMethodModifiers.None)
{
}
public Expression Selector { get; set; }
public ParameterExpression Parameter { get; set; }
public string Column { get; set; }
public CheckMethod Method { get; set; }
public CheckMethodModifiers Modifiers { get; set; }
public string Value { get; set; }
}
Usage:
var column = typeof(TEntity).Name + "ID";
var where = from id in SelectedIds
select new WhereSpecifier(column, CheckMethod.Equal, id.ToString());
return GetTable().Where(where);
I tried #Egor Pavlikhin solution but i got "The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.".
According to this you can use PredicateExtensions :
var predicate = PredicateExtensions.Begin<User>();
foreach (var name in names)
{
pr = pr.Or(x => x.Name == name);
}
return _context.Users.Where(predicate);
Don't forget that entity framework also understands entity sql, so you can do this part of the query in a string. Building a string up is pretty convenient when you have dynamic stuff you need to do.
I had to construct the predicate for the 'Where' clause dynamically based on User Interface selections. 'System.Dynamic.Linq' allows to predicates from strings.
foreach (var name in names)
{
query = query.Where("Name=#0 And UserName=#1", name, name);
}
return query;
'System.Dynamic.Linq' is available as a nuget package. Check out Scott Guthrie's introduction to the topic here.
i found this way it is too simple :
var query = context.InvoiceHeader.Where( i => i.DateInvoice >= model.datedu && i.DateInvoice <= model.dateau).AsQueryable();
if(model.name != null)
{
query = query.Where(i => i.InvoiceNum.Equals(model.name));
}
if (model.status != 0 )
{
query = query.Where(i => i.REF_InvoiceStatusRecId == model.status);
}
if (model.paiements != 0)
{
query = query.Where(i => i.REF_PaymentTermRecId == model.paiements);
}
query = query.AsQueryable().OrderByDescending(x => x.RecId);

Categories