2010-11-05 94 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