2010-11-05 103 views
3

我想通過f#linq創建一個「IN CLause」,但似乎無法得到它。我已經嘗試了兩種選擇:FLinq SQL「IN子句」

迭代天的列表作爲序列表達式的一部分:

let getHistoricalQuotes (securityId:int) (days:string seq) = 
    let results = 
     Query.query <@ seq { 
      for day in days do 
       for sq in db.SecurityQuote do 
        if sq.SecurityId =?! securityId && sq.Day = day then 
         yield sq ; 
     } @> 

並有List.exists條款:

let getHistoricalQuotes (securityId:int) (days:string list) = 
    let results = 
     Query.query <@ seq { 
      for sq in db.SecurityQuote do 
       if sq.SecurityId =?! securityId && List.exists (fun d -> d = sq.Day) days then 
        yield sq ; 
     } @> 

    results 

兩者都是給我:

base {System.SystemException} = {「Method 'Microsoft.FSharp.Cor e.FSharpFunc 2[System.String,System.Boolean] ToFSharpFunc[String,Boolean](System.Converter 2 System.String,System.Boolean])」 沒有支持轉換爲SQL。「}

一如既往,感謝提前的幫助......


改寫到:

let getHistoricalQuotes (securityId:int) (days:string list) = 
    let results = 
     Query.query <@ 
      Query.join 
       db.SecurityQuote 
       days 
       (fun sq -> if(sq.SecurityId =?! securityId) then sq.Day else "") 
       (fun d -> d) 
       (fun sq d -> sq) @> 

    results 

,並得到這個excepion:

System.Exception未處理
消息=以下構造爲 ,用於查詢但未被 識別爲F#到LINQ查詢轉換器:值 ([「2010/01/04」; 「2010/02/01」; 「2010/03/01」; 「2010/04/01」; 「2010/05/03」; 「2010/06/01」; 「2010/07/01」; 「2010/08/02」; 「2010/09/01」; 「2010/10/01」; 「2010/11/01」; 「2010/12/01」; 「2010/01/29」; 「2010/02/26」; 「2010/03/31」; 「2010/04/30」; 「2010/05/31」; 「2010/06/30」; 「2010/07/30」; 「2010/08/31」; 「2010/09/30」; 「2010/10/29」; 「2010/11/30」; 「2010/12/31」])這是 不是有效的查詢表達式。檢查 允許的查詢規範 ,並考慮將一些查詢 出報價

的和去除的報價並不會導致錯誤 - 但它產生了令人難以置信的不正確的查詢(selext *從historicalquote)


作弊現在,直到我能回來,並解決問題 - 但至少我能保持簽名一樣,雖然我會顛簸數據庫。下面我

let getHistoricalQuotes (securityId:int) (days:string list) = 
    let getQuote (day) = 
     Query.query <@ seq { 
      for sq in db.SecurityQuote do 
       if sq.SecurityId =?! securityId && sq.Day = day then 
        yield sq ; 
     } @> |> Seq.head 

    List.map (fun day -> getQuote day) days 

每威爾試過這種

let getHistoricalQuotes (securityId:int) (days:string list) = 
    let results = 
     Query.query <@ seq { 
      for sq in db.SecurityQuote do 
       if sq.SecurityId =?! securityId && days.Contains(sq.Day) then 
        yield sq ; 
     } @> 
    results 

不過,這並不編譯

錯誤1場,構造或 成員 '包含' 沒有定義


最後 - (謝謝你會):

let getHistoricalQuotes (securityId:int) (days:string array) = 
    let results = 
     Query.query <@ seq { 
      for sq in db.SecurityQuote do 
       if sq.SecurityId =?! securityId && days.Contains(sq.Day) then 
        yield sq ; 
     } @> 
    results 

是的 - 你需要打開System.Linq的 - 那些是擴展方法,或者在ELAST部分 - 它們必須是,

+0

我剛纔讀的地方,F#可能不支持消費的擴展方法...我正在尋找一個替代... HTTP:/ /stackoverflow.com/questions/777247/using-extension-methods-defined-in-c-from-f -code – Will 2010-11-05 21:58:29

+0

嘗試System.Linq.Enumerable.Contains(days,day)..假設F#支持使用泛型方法.. – Will 2010-11-05 22:03:14

+0

很高興能有所幫助,而且很好看到F#支持擴展 - 它們是很好的語法糖。使用'open System.Linq',查看其他方法掛在任何IEnumerable對象上 - 這裏有很多可用的東西,大多數使用EF。歡呼 – Will 2010-11-09 04:30:22

回答

2

它已經存在於LINQ的,而是對你使用的正好相反:

days.Contains(day) 
+0

它不適合我。 '包含'未定義。我必須把它放在錯誤的地方。我正在編輯... – akaphenom 2010-11-05 21:09:17

+0

我是一名C#開發人員,幾乎不能讀取F#,但Contains是.Net框架的一部分,因此應該適用於所有語言。我通常編寫類似下面的代碼:'var validValues = new [] {1,2,3}; var result = source.Where(item => validValues.Contains(item.Property1));'希望你可以閱讀C#並翻譯... – Will 2010-11-05 21:14:57

+0

我認爲你正在導入/使用System.Linq? (或任何相當於F#的語句) – Will 2010-11-05 21:16:05