1. 程式人生 > >xBIM 使用Linq 來優化查詢

xBIM 使用Linq 來優化查詢

方法重載 查詢語句 何事 現實 類型 做到 ray amp color

目錄

  • xBIM 應用與學習 (一)

  • xBIM 應用與學習 (二)

  • xBIM 基本的模型操作

  • xBIM 日誌操作

  • XBIM 3D 墻壁案例

  • xBIM 格式之間轉換

  • xBIM 使用Linq 來優化查詢

  • xBIM IFC 輸出 Excel 報表

  • xBIM IFC 層次結構

  • xBIM 多個IFC文件合並

  • xBIM 插入復制功能

  • XBIM 基於 WexBIM 文件在 WebGL 瀏覽和加載

在前幾篇博客中,查詢都基本是循環部分案例也使用了Linq。Linq 代表一個語言集成查詢。它是從3.5版本開始的.NET Framework的一部分。它實現了延遲執行,這意味著你可以鏈接查詢語句,它將不會做任何事情,直到你實際叠代結果。您可以使用LINQ作為一個

特定的語言,也可以使用擴展方法System.Linq延伸IEnumerable<T> 的接口,並能得到參數作為lambda表達式。我們更喜歡後面的方法,但它是相同的。下面的例子顯示了兩個變種做同樣的事情。這兩個查詢的結果是枚舉具有任何開放的墻的全局唯一ID。

// Ling 表達式
var
ids = from wall in model.Instances.OfType<IIfcWall>() where wall.HasOpenings.Any() select wall.GlobalId;
// 使用 Lambda表達式
var
ids = model.Instances .Where<IIfcWall>(wall => wall.HasOpenings.Any()) .Select(wall => wall.GlobalId);

可以在代碼中看到我們Where()直接調用了函數IModel.InstancesIEntityCollection實現實現了像大多數的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倍!請不要使用這種類型的代碼:

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();
    }
}

xBIM 使用Linq 來優化查詢