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.