2013-03-18 63 views
2

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

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

我使用这三个distance_to允许在8次不同的查询,有没有什么办法让那些认为我可以在我的查询使用模板?

+0

是这些查询来自相同的方法发生? – dasblinkenlight 2013-03-18 09:48:05

+0

不同的方法 – 2013-03-18 09:48:39

回答

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) 
    // ... 
+0

除了WHERE语句之外,预编译我的整个查询是否是一个好主意? – 2013-03-18 10:09:17

+0

这几乎是我的偏好问题。我更喜欢的方法是将查询提取到一个方法并传递一个谓词函数:RouteQuery(route => {return route.endpoints.Any(...);})' – fjdumont 2013-03-18 12:01:29