Composable FLinq expressions

Posted by Daniel on Stack Overflow See other posts from Stack Overflow or by Daniel
Published on 2010-04-26T17:11:08Z Indexed on 2010/04/26 17:13 UTC
Read the original article Hit count: 157

Filed under:
|

When doing linq-to-sql in c#, you could do something like this:

var data = context.MyTable.Where(x => x.Parameter > 10); 

var q1 = data.Take(10); 
var q2 = data.Take(3); 

q1.ToArray(); 
q2.ToArray(); 

This would generate 2 separate SQL queries, one with TOP 10, and the other with TOP 3. In playing around with Flinq, I see that:

let data = query <@ seq { for i in context.MyTable do if x.Parameter > 10 then yield i } @> 

data |> Seq.take 10 |> Seq.toList 
data |> Seq.take 3 |> Seq.toList 

is not doing the same thing. Here it seems to do one full query, and then do the "take" calls on the client side. An alternative that I see used is:

let q1 = query <@ for i in context.MyTable do if x.Param > 10 then yield i } |> Seq.take 10 @> 
let q2 = query <@ for i in context.MyTable do if x.Param > 10 then yield i } |> Seq.take 3 @> 

These 2 generate the SQL with the appropriate TOP N filter. My problem with this is that it doesn't seem composable. I'm basically having to duplicate the "where" clause, and potentially would have to duplicate other other subqueries that I might want to run on a base query. Is there a way to have F# give me something more composable?

(I originally posted this question to hubfs, where I have gotten a few answers, dealing with the fact that C# performs the query transformation "at the end", i.e. when the data is needed, where F# is doing that transformation eagerly.)

© Stack Overflow or respective owner

Related posts about F#

Related posts about linq-to-sql