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

时间:2016-01-21 07:30:00

标签: c# entity-framework linq linq-to-entities

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

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

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

  1. 将数据库中的所有条目放入容器中,并计算距离并在foreach循环中过滤条目。
  2. 按距离过滤,并在转换为OutputModel时重新计算距离。
  3. 是否可以一次性执行此操作(首选DB本身的计算)?

4 个答案:

答案 0 :(得分:0)

你可以做inputlist.where(....)。select(x =&gt; calculatedistance).select(dist =&gt; new outputmodel)...从我的手机评论所以不能输出完整的语句。但是应该指出你正确的方向。基本上。拳头在那里选择距离。然后选择输出模型

答案 1 :(得分:0)

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

请试一试

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

答案 2 :(得分:0)

假设您的目标是同时使用您从实体计算的距离和您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 :(得分:0)

LINQ查询语法自然支持let子句。

以下是如何将其应用于您的方案:

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