2011-02-10 4 views
3

저는 SQL 서버에 UDF 및 저장된 procs에 F # 및 Linq를 사용하려고하는 프로젝트에서 작업하고 있습니다. 그 중 일부는 모든 유효한 쿼리, 정렬 기준 및 쿼리 결과 채점 방법을 정적으로 정의하는 것이 었습니다.linq 쿼리에 많은 인용문 작성하기

저는 지금까지 상당히 성공적 이었지만 sortBy 표현식을 구성하는 데 심각한 어려움을 겪고 있습니다.

여기이 그렇게

let execQuery = fun (predicates,sorts,scorer) -> 
    <@ seq { for prod in (%dc).Products do 
       if (%predicates) prod then yield prod } 
     |> (%sorts) 
     |> (%scorer) @> 

이러한 기본적인 아웃 라인을 사용하여 같은 쿼리 실행기에서 나중에 사용되는 끝 기본 개념

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 @> 

의 모든 것이 한 내가 (사용하지 않는 작동 % 정렬). 필자는 이것을 통과 할 때마다 F #에서 Linq 번역기로 인식하지 못한다. 나는 combinators를 사용하여 여러 가지 시도를 시도했지만, 나는 뭔가를 놓치고있어.

<@ Seq.sortBy (fun prod -> prod.Name) |> Seq.sortBy (fun prod -> prod.Style) @> 

다음과 같이 정렬 기능을 스텁으로 처리하면 정상적으로 작동합니다. 그러나이 같은 연결자를 사용하여 :

let (|>*) = fun f g -> <@ fun c -> ((%f) c) |> (%g) @> 

하지 않는 ..

어떤 아이디어?

답변

1

불행히도이 질문에 대한 좋은 답변이 없습니다.

F # LINQ 변환기가 현재 쿼리 구조에 매우 민감합니다. 작곡을 사용하면 직접 쓴다면 똑같은 인용문을 얻을 수 있기 때문에 직접 쓴다면 똑같은 것을 만들어야 할 수도 있습니다.

은 분류기와 예를 들어, (나는 그것을 시도하지 않은,하지만 난이 작품 일반적인 코드와 정확히 같은 인용 생산해야한다고 생각) 같은 것을해야 할 수 있습니다

let (|>*) f g = fun c -> <@ (%c) |> (%f) |> (%g) @> 

<@ seq { for prod in (%dc).Products do 
      if (%predicates) prod then yield prod } @> |> 
(<@ Seq.sortBy (fun prod -> prod.Name) @> |>* 
    <@ Seq.sortBy (fun prod -> prod.Style) @>) 

문제를 따옴표에 람다 함수를 포함 시키면 F # 변환기가이를 처리해야합니다. 그렇지 않으면 LINQ에서 SQL 로의 변환기가 실패 할 것이므로 부분적으로 평가해야합니다. 이 문제는 아주 까다로운 경우가 있습니다 ...

그러나 F # 팀은 최근이 분야에서 몇 가지 개선 사항을 수행해 왔습니다. 가장 좋은 방법은 간단한 재현 사례를 찾아 fsbugs마이크로 소프트 dot com으로 보내주십시오. PowerPack 릴리스는 "민감한"것이 아니므로 테스트를 통해 도움을 요청하고 제공하면 (약속 없음) 최근 변경 사항으로 소스 코드를 얻을 수 있습니다.