LINQ表明語言集成查詢,它是3.5版以來的.NET Framework的一部分。它實現延遲執行,這意味着您能夠連接查詢語句,而且在您實際迭代結果以前它將不執行任何操做。您可使用LINQ做爲一個特定的語言,也可使用擴展方法,從 System.Linq
延伸 IEnumerable<T>
的接口,並能獲得參數做爲lambda表達式。咱們更喜歡後一種方法,但它是等效的。如下示例顯示了兩種變體都作一樣的事情。兩個查詢的結果都是枚舉具備任何開口的牆的全局惟一ID。html
// LINQ 表達式 var ids = from wall in model.Instances.OfType<IIfcWall>() where wall.HasOpenings.Any() select wall.GlobalId;
//Lambda 表達式。效果與上述的 Linq 表達式相同 var ids = model.Instances .Where<IIfcWall>(wall => wall.HasOpenings.Any()) .Select(wall => wall.GlobalId);
能夠在代碼中看到 Where()
直接調用函數IModel.Instances
。IEntityCollection
實現實現了像大多數的LINQ的數據檢索方法重載 Where<T>()
,Count<T>()
,FirstOrDefault<T>()
,OfType<T>()
,它是在最低水平快速數據訪問進行了優化。全部這些方法都返回IEnumerable<T>,
所以您可使用其餘方法將其連接以執行進一步的選擇,聚合,排序和其餘操做。 IEntityCollection
函數也使用延遲執行,所以它很是適合Linq概念。若是要屢次使用結果,則應強制它枚舉。你能夠經過調用一個作到這一點ToList<T>()
,ToArray<T>()
或ToDictionary<T>()
方法。函數
xBIM在內部使用實體類型做爲第一級過濾器,所以您應始終詢問最具體的類型。請記住,它IModel.Instances
包含模型中的全部實體,一般是數十萬個對象!因此你不想迭代全部這些來作任何事情。請參閱如下好的和壞的示例,它們執行相同但不徹底相同的操做:優化
public static void SelectionWithLinq() { const string ifcFilename = "SampleHouse.ifc"; var model = IfcStore.Open(ifcFilename); using (var txn = model.BeginTransaction()) { var requiredProducts = new IIfcProduct[0] .Concat(model.Instances.OfType<IIfcWallStandardCase>()) .Concat(model.Instances.OfType<IIfcDoor>()) .Concat(model.Instances.OfType<IIfcWindow>()); // 遍歷你所須要的實體,大概有9個 foreach (var product in requiredProducts) { // 相關業務邏輯 } txn.Commit(); } }
下面的代碼示例大約慢了4.5倍!請不要使用這種類型的代碼:ui
public static void SelectionWithoutLinqIsSLOW() { const string ifcFilename = "SampleHouse.ifc"; var model = IfcStore.Open(ifcFilename); using (var txn = model.BeginTransaction()) { //這種方式須要迭代大約 47309 個實體,而不是僅須要9個實體。 foreach (var entity in model.Instances) { if (entity is IIfcWallStandardCase || entity is IIfcDoor || entity is IIfcWindow) { // 最好不要在這裏作其餘的業務邏輯 } } txn.Commit(); } }