For example, say you wanted to retrieve a list of category names of all elements that exist in the active view. To achieve this without LINQ you would:
- Select all elements in the active view (using a FilteredElementCollector).
- Loop through each element and:
- Check that category is not null.
- Check that you haven't already stored this category name (you don't want to see the Doors category 100 times).
- Store the category in a list.
- Sort the list so that it is in alphabetical order.
Using LINQ this can be reduced to:
- Select all elements in the active view (using a FilteredElementCollector).
- Select all category names from the elements.
- Ensure the list of category names contains only distinct items and is in alphabetical order.
using System.Linq;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace KRSP.DistinctCategories
{
[Transaction(TransactionMode.Automatic)]
public class Command : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication app = commandData.Application;
UIDocument doc = app.ActiveUIDocument;
View view = doc.ActiveView;
//select all elements in the active view
FilteredElementCollector allInView = new FilteredElementCollector(doc.Document, view.Id);
allInView.WhereElementIsNotElementType();
//use LINQ to collect the category names of all elements whilst ensuring that category is not null
var categoryNames = from elem in allInView
where elem.Category != null
select elem.Category.Name;
//strip out duplicates and order the list of category names
categoryNames = categoryNames.Distinct().OrderBy(catName => catName);
//construct a string list of the collected category names
string catList = "Categories:";
foreach (var catName in categoryNames)
{
catList += "\n" + catName;
}
//display a dialog showing the results.
TaskDialog td = new TaskDialog("INFO");
td.MainInstruction = string.Format("{0} Categor{1} Found.", categoryNames.Count(), categoryNames.Count() == 1 ? "y" : "ies");
td.MainContent = catList;
td.Show();
return Result.Succeeded;
}
}
}
Lets examine the LINQ statement above:
//use LINQ to collect the category names of all elements whilst ensuring that category is not null
var categoryNames = from elem in allInView
where elem.Category != null
select elem.Category.Name;
There are three parts to the query:- The "from/in" clause; this is where you define which collection you are querying. In this example we are querying the "elem" items inside the "allInView" FilteredElementCollector.
- The "where" clause; this clause is optional and allows us to conditionally filter the selection. In this example we are only selecting those elements whose categories are not null.
- The "select" clause; this is where we state what we want to retrieve from the collection. In this example we are retrieving the "Category.Name" of each "elem" item.



