Quand vous faites LINQ to SQL en C#, vous pouvez faire quelque chose comme ceci:Composable FLinq expressions
var data = context.MyTable.Where(x => x.Parameter > 10);
var q1 = data.Take(10);
var q2 = data.Take(3);
q1.ToArray();
q2.ToArray();
Cela générerait 2 requêtes SQL séparées, une avec TOP 10, et l'autre avec les 3 meilleurs. En jouant avec Flinq, je vois que:
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
ne fait pas la même chose. Ici, il semble faire une requête complète, puis faire les appels "prendre" sur le côté client. Une alternative que je vois utilisée est:
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 @>
Ces 2 génèrent le SQL avec le filtre TOP N approprié. Mon problème avec ceci est que cela ne semble pas composable. Je dois essentiellement dupliquer la clause "where", et éventuellement dupliquer d'autres sous-requêtes que je pourrais vouloir exécuter sur une requête de base. Y a-t-il un moyen de faire que F # me donne quelque chose de plus composable?
(je l'origine posted this question to hubfs, où je l'ai obtenu quelques réponses, portant sur le fait que C# effectue la transformation de requête « à la fin », à savoir lorsque les données sont nécessaires, où F # fait que la transformation avec impatience.)