Я работаю над проектом, в котором я пытаюсь использовать F # и Linq для пользовательских функций и хранимых процедур на сервере SQL.Часть этого состояла в том, чтобы статически определить все действительные запросы, критерии сортировки и средства оценки результатов запросов.
До сих пор я был довольно успешным, но столкнулся с серьезнымсложность составления выражений sortBy.
Вот базовая концепция
let sorter =
let exprMap:Map<string,Quotations.Expr<seq<Product> -> seq<Product>>> =
Map.ofList
["ProductName",<@ Seq.sortBy (fun prod -> prod.Name) @> ]
// .. more entries ..
let sortBuilder sortkeys =
Array.foldBack
(fun criteria acc -> <@ %(exprMap.[criteria]) >> (%acc) @>)
sortkeys
<@ Seq.map id @>
Это в конечном итоге будет использовано позже в исполнителе запросов, например:
let execQuery = fun (predicates,sorts,scorer) ->
<@ seq { for prod in (%dc).Products do
if (%predicates) prod then yield prod }
|> (%sorts)
|> (%scorer) @>
Используя эти основные схемывсе работает, пока я не пользуюсь (% sorts).Каждый раз, когда я передаю это, меня не узнают в F # переводчику Linq.Я пробовал несколько разных попыток использования комбинаторов, но у меня есть ощущение, что я что-то упустил.Если я отключу функцию сортировки со следующим
<@ Seq.sortBy (fun prod -> prod.Name) |> Seq.sortBy (fun prod -> prod.Style) @>
, она будет работать, как и ожидалось.Однако использование комбинатора, как это:
let (|>*) = fun f g -> <@ fun c -> ((%f) c) |> (%g) @>
не ..
Есть идеи?