C#在LINQ中定义LET

时间:2013-03-18 09:44:16

标签: c# linq templates let

我有多个使用相同LET变量的LINQ查询,我想以某种方式预定义这些。

IQueryable<RouteQueryModel> query =
    (from b in db.routes
     let avg_rating = b.ratings.Any() ? 
         b.ratings.Select(r => r.rating1).Average() : 
         0
     let distance_to_first_from_me = b.coordinates.
         Select(c => c.position).
         FirstOrDefault().
         Distance(DbGeography.FromText(currentLocation, 4326))
     let distance_to_last_from_me = b.coordinates.
         OrderByDescending(c => c.sequence).
         Select(d => d.position).
         FirstOrDefault().
         Distance(DbGeography.FromText(currentLocation, 4326))
     let distance_to_from_me = distance_to_first_from_me < distance_to_last_from_me ? 
         distance_to_first_from_me : 
         distance_to_last_from_me
     where b.endpoints.Any(e => values.Any(t => t == e.town.town_id))
     select new RouteQueryModel 
     { 
         b = b, 
         distance_to_from_me = distance_to_from_me.Value, 
         avg_rating = avg_rating
     }
 );

我在8个不同的查询中使用了这三个distance_to LET,有没有办法为那些我可以在查询中使用的模板制作模板?

1 个答案:

答案 0 :(得分:5)

pre-compile LINQ Queries有一种简单的方法:

var distanceToFirstFromMe =
    CompiledQuery.Compile<Route, GeoCoordinates, Distance>((route, currentLocation) => {
        return route.coordinates
            .Select(c => c.position)
            .FirstOrDefault()
            .Distance(DbGeography.FromText(currentLocation, 4326));
    });

要在查询中使用它们,您只需调用它们:

IQueryable<RouteQueryModel> query =
    (from b in db.routes
     let avg_rating = b.ratings.Any() ? 
         b.ratings.Select(r => r.rating1).Average() : 0
     let distance_to_first_from_me = distanceToFirstFromMe(b, currentLocation)
     // ...