2012-04-30 45 views
3

我想用最近推出的F#3.0查詢理解語法來定義Bill of Materials種類的查詢。儘管可以使用yield!對內存集合進行seq解析來定義這些查詢,但我並不缺乏將這些查詢翻譯爲針對遠程IQueryable源的查詢解析。我想最難的部分將是「訓練」提供者使用遞歸模式識別公用表表達式。遞歸查詢理解(F#3.0)

任何想法?

+0

我不希望成爲討厭的人,但如果你打算再次在這裏發帖,你可以看看這個:http://stackoverflow.com/faq#signatures你不需要簽名或標語事實上它有點令人沮喪。 –

回答

5

不幸的是,我不認爲F#3.0中的當前查詢語法支持能夠處理遞歸查詢。主要問題在於F#3.0依賴於主要爲C#設計的標準IQueryable實現,因此它們不期望遞歸結構。

我認爲支持這將是相當困難的。您可以將自己的F#語句實現爲SQL翻譯器(這很難),也可以實現某種類型的預處理器,該語言採用包含遞歸的F#語句(查詢),並將遞歸轉換爲LINQ to SQL翻譯器可以處理(但這可能很難)。

一般來說,方法是定義自己的查詢生成器:

open System.IO 
open Microsoft.FSharp.Quotations 

type MyQueryBuilder() = 
    member x.For(a, body) = Seq.collect body a 
    member x.Quote(e) = e 
    member x.YieldFrom(s) = s 
    member x.Run(e:Expr<'T>) : 'T = failwithf "%A" e 

// Example using the custom query builder 
// (fails, printing the quoted query) 
let mquery = MyQueryBuilder()  
let n = [1 .. 10] 

let rec nums a : seq<int> = 
    mquery { for b in n do 
      yield! nums b } 

Run方法,你會得到一個代表查詢報價。您可以預先處理該操作,並將所有呼叫替換爲MyQueryBuilder,同時調用標準query操作,並用其他操作替換遞歸。然後,您可以撥打query.Run(運行標準IQueryable實施)。

雖然如我所說,這可能會很難實現 - 但也許,如果你有一些你可以輕易處理的特定類型的遞歸,它可能是一個選項。但是,如果LINQ to SQL沒有爲任何標準模式生成公共表格表達式,那麼我認爲您不可以培訓它來生成它們 - 據我所知,翻譯器不是真正可擴展的。