Linq:按计算结果过滤并重用此结果

Posted

技术标签:

【中文标题】Linq:按计算结果过滤并重用此结果【英文标题】:Linq: Filter by calculation result and reuse this result 【发布时间】:2016-04-27 08:15:43 【问题描述】:

我有一个集合(在 DbSet 中),我想按其属性(距离)的计算结果对其进行排序,并将其转换(重新使用距离)到不同的模型。每个条目只应进行一次计算(作为 DbSet,它将在数据库本身中执行)。

class InputModel 
    Vector3 position;


class OutputModel 
    double distance;


var inputList = getInputList(); // returns IQueryable<InputModel>

var outputList = inputList
.Where( x => ()
    var dist = calculateDistance( x.position );
    // calculateDistance() boils down to a simple equation that could directly translated to an sql-query (when typed in statically by hand)
    return dist < maxDistance;
)
.Select( x => () 
    return new OutputModel 
        distance = ???; // get the calculated distance somehow
)
.ToList();

我想到了两种可能的解决方案:

    将数据库中的所有条目放入容器中,然后计算距离并在 foreach 循环中过滤条目。 在转换为 OutputModel 时按距离过滤并重新计算距离。

是否可以一次性完成(最好是在数据库中计算)?

【问题讨论】:

1. Linq to Entities 提供商不允许您在 Where() 中使用 calculateDistance()。显示它的代码,以便我们知道它是否可以分解为提供者能够翻译的东西。 2. getInputList() 是否返回 IQueryable&lt;InputModel&gt; calculateDistance() 是 db (SQL) 支持的一个简单的数学函数(但是我不知道它是否会直接转换为 sql-statements,我对此没有任何经验)。是的,IQueryable&lt;InputModel&gt; 是要处理的容器。 【参考方案1】:

您可以执行 inputlist.where(....).select(x=>calculatedistance).select(dist=> new outputmodel)... 从我的手机评论,因此无法输入完整的语句。但应该指出你正确的方向。基本上。拳头做where然后选择距离。然后选择输出模型

【讨论】:

【参考方案2】:

假设您的目标是使用您计算的与实体的距离和实体本身进行OutputModel 投影,您只需在执行计算时将其实体作为匿名类型投影计算:

var outputList = inputList
    .Select( x => new 
        
            dist = calculateDistance( x.position ),
            entity = x
         )
    .Where( x => x.dist < maxDistance )
    .Select( x => new OutputModel 
        
            distance = x.dist,
            // and you have access to source entity via `x.entity`
         )
    .ToList();

【讨论】:

【参考方案3】:

您可以先进行选择,然后在比较中使用选择的值。

请试一试

var outputList = InputList
                 .Select(
                     x => new 
                      
                        dist = calculateDistance( x.position )
                           
                  )
                 .Where(x => x.dist < maxDistance)
                 .Select(y => () 
                 return new OutputModel 
                     distance = y.dist // get the calculated distance Here
                 );

【讨论】:

【参考方案4】:

LINQ 查询语法通过let 子句自然支持这一点。

以下是如何将其应用于您的场景:

var outputList = 
    (from x in inputList
     let distance = ... // distance calculation expression using x
     where distance < maxDistance
     select new OutputModel  distance 
    ).ToList();

【讨论】:

以上是关于Linq:按计算结果过滤并重用此结果的主要内容,如果未能解决你的问题,请参考以下文章

数据库查询优化技术

在 LINQ to Entities 中重用选择表达式

Mysql查询优化从入门到跑路数据库查询优化技术总揽

从子查询中保存价值并在以后重用它?

重用语句和结果集是不是会释放其先前使用的资源?还是我必须在重用之前明确关闭它们?

嵌套在 UIScrollView 中时保持 UITableView 的重用能力