Predefined queries were introduced in Sitecore 7 Update 1. They're a very powerful slight of hand. Any object returned by the ContentSearch API (inherits SearchResultItem) can now be decorated with PredefinedQuery attribute that gets added to any query.
This allows to streamline our LINQ queries by pushing filtering logic into our domain objects. Pretty slick. Let's start with a simple class with one decorator:
[PredefinedQuery("_templatename", ComparisonType.Equal, "product"]
public class Product : SearchResultItem
{
public string Name { get; set; }
public string Description { get; set; }
}
We can now simplify our LINQ query because all Product queries will have _templatename == "product" added automatically.
// Before PredefinedQuery
var results = context.GetQueryable()
.Where(item => item.TemplateName == "Product")
.ToList();
// After!!
var results = context.GetQueryable().ToList();
This can become even more powerful by stacking PredefinedQuery attributes. Now without modifying our query we're able to scope our results to Products that are active.
[PredefinedQuery("_templatename", ComparisonType.Equal, "product"]
[PredefinedQuery("active", ComparisonType.Equal, "1"]
public class Product : SearchResultItem
{
public string Name { get; set; }
public string Description { get; set; }
}
Note
The field names are the index-based field names declared in the <fieldMap /> and <fields hint="raw:AddComputedIndexField /> sections (among others) of your ContentSearch config. So key off the index fields, not the Sitecore fields.
Have fun with it.