zoukankan      html  css  js  c++  java
  • xBIM 基础14 使用LINQ实现最佳性能(优化查询)

           LINQ代表语言集成查询,它是3.5版以来的.NET Framework的一部分。它实现延迟执行,这意味着您可以链接查询语句,并且在您实际迭代结果之前它将不执行任何操作。您可以使用LINQ作为一个特定的语言,也可以使用扩展方法,从 System.Linq 延伸 IEnumerable<T> 的接口,并能得到参数作为lambda表达式。我们更喜欢后一种方法,但它是等效的。以下示例显示了两种变体都做同样的事情。两个查询的结果都是枚举具有任何开口的墙的全局唯一ID。

    // 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.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();
        }
    }
     
  • 相关阅读:
    领域驱动和MVVM应用于UWP开发的一些思考
    UWP中实现自定义标题栏
    UWP中新加的数据绑定方式x:Bind分析总结
    MVVM框架从WPF移植到UWP遇到的问题和解决方法
    UWP学习目录整理
    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息
    MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
    MVVM设计模式和WPF中的实现(四)事件绑定
    MVVM模式解析和在WPF中的实现(三)命令绑定
    MVVM模式和在WPF中的实现(二)数据绑定
  • 原文地址:https://www.cnblogs.com/SavionZhang/p/10983383.html
Copyright © 2011-2022 走看看