3

クエリ式演算子の順序は重要ですか? Idk ですが、(一部の選択では) 実行される場合もありますが、実行されない場合もあります (または、実行されるが特定の状況を暗黙的に処理する場合もあります)。

select演算子が最後に行かなければならないことは必須ですか? ほとんどすべての組み合わせで、最後のステートメントとして記述しないと文句を言いますが、take nの場合、この演算子はselectの後に行くことができます

実行プロセスがどのように機能するかだけに興味がありますか?

これは私に別の質問をもたらします。Iterable コレクションを反復処理し、最初の反復で 1 つ (最初) の値を選択する場合、その 1 つ (最初) の値に対して順序はどのように機能しますか? 最初にシーケンスを返し、次にそのシーケンスで順序を実行した場合は明らかですが、反復ごとにsortByを実行するようです(?)。実行されたアルゴリズムの設計がどのようなものであるかに興味があります。

これがクエリ式の私の例です。

let sq = query {
   for p in datasource do
   where p.age>20
   sortBy p.age
   select p
}

説明をいただければ幸いです。

ありがとう

4

2 に答える 2

3

We don't need to guess, we can find out.

let sample = Seq.init 10 (fun i -> i * 10) |> Seq.map (fun i -> { age =  i }) 
let sq = query {
   for p in sample do
   where (p.age > 20)       
   sortBy p.age
   select p
}

sq |> Seq.toList |> ignore

The generated IL (cleaned up) looks like

IL_004e: newobj instance void Program/sq@16::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder)
IL_0053: callvirt instance [...] For<class Program/Person,      
IL_005d: callvirt instance [...] Where<class Program/Person,    
IL_0067: callvirt instance [...] SortBy<class Program/Person,   
IL_0071: callvirt instance [...] Select<class Program/Person,   

Suppose we change the order of sortBy

let sq = query {
   for p in sample do
   sortBy p.age
   where (p.age > 20)       
   select p
}

The new IL will be:

IL_006c: callvirt instance [...] For<class Program/Person,      
IL_0076: callvirt instance [...] SortBy<class Program/Person,   
IL_0080: callvirt instance [...] Where<class Program/Person,    
IL_008a: callvirt instance [...] Select<class Program/Person,   

You can clearly see that it follows the exact order you define the query in. This wouldn't matter for T-SQL comprehensions because the query will be translated by an Expression visitor, but for object queries, query expressions are pretty much just syntactic sugar for you.

于 2016-12-09T18:37:46.090 に答える