如何在F#中组成查询表达式?

编程入门 行业动态 更新时间:2024-10-22 20:32:01
本文介绍了如何在F#中组成查询表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我一直在这里查询查询表达式 msdn .microsoft/en-us/library/vstudio/hh225374.aspx

I've been looking at query expressions here msdn.microsoft/en-us/library/vstudio/hh225374.aspx

我一直想知道为什么以下内容是合法的

And I've been wondering why the following is legitimate

let testQuery = query { for number in netflix.Titles do where (number.Name.Contains("Test")) }

但是你真的不能做这样的事情

But you can't really do something like this

let christmasPredicate = fun (x:Catalog.ServiceTypes.Title) -> x.Name.Contains("Christmas") let testQuery = query { for number in netflix.Titles do where christmasPredicate }

当然F#允许这样的可组合性,所以您可以重用谓词??如果我想将圣诞节标题与另一个谓词(例如在特定日期之前)结合起来怎么办?我必须复制并粘贴整个查询吗? C#与此完全不同,它具有几种构建和组合谓词的方法

Surely F# allows composability like this so you can reuse a predicate?? What if I wanted Christmas titles combined with another predicate like before a specific date? I have to copy and paste my entire query? C# is completely unlike this and has several ways to build and combine predicates

推荐答案

对于需要显式引号的F#2.0版本的查询,这很容易做到(我写了有关它的博客文章).有一种方法可以在C#中实现类似的目的(另一个博客文章),我认为类似的技巧可能是在F#3.0中玩过.

This was quite easy to do with the F# 2.0 version of queries which required explicit quotations (I wrote a blog post about it). There is a way to achieve similar thing in C# (another blog post) and I think similar tricks could be played with F# 3.0.

如果您不介意较丑陋的语法,则也可以在F#3.0中使用显式引号.当你写 query { .. }编译器实际上生成如下内容:

If you do not mind uglier syntax, then you can use explicit quotations in F# 3.0 too. When you write query { .. } the compiler actually generates something like:

query.Run(<@ ... @>)

其中<@ .. @>中的代码用F#代码引用-即,以Expr类型存储的代码代表源代码,并且可以转换为LINQ表达式,从而转换为SQL.

where the code inside <@ .. @> is quoted F# code - that is, code stored in an Expr type that represents the source code and can be translated to LINQ expressions and thus to SQL.

这是我使用SqlDataConnection类型提供程序进行测试的示例:

Here is an example that I tested with the SqlDataConnection type provider:

let db = Nwind.GetDataContext() let predicate = <@ fun (p:Nwind.ServiceTypes.Products) -> p.UnitPrice.Value > 50.0M @> let test () = <@ query.Select ( query.Where(query.Source(db.Products), %predicate), fun p -> p.ProductName) @> |> query.Run |> Seq.iter (printfn "%s")

关键技巧是,当您使用显式报价(使用<@ .. @>)时,可以使用%运算符进行报价切片.这意味着predicate的引号将放在您写%predicate的地方的查询的引号中(在test中).

The key trick is that, when you use explicit quotations (using <@ .. @>) you can use the % operator for quotation slicing. This means that the quotation of predicate is put into the quotation of the query (in test) in place where you write %predicate.

与漂亮的查询表达式相比,代码很丑陋,但是我怀疑您可以通过在此之上编写一些DSL或对报价进行预处理来使它更好.

The code is quite ugly compared to the nice query expression, but I suspect you could make it nicer by writing some DSL on top of this or by pre-processing the quotation.

编辑:稍加努力,实际上就有可能再次使用query { .. }语法.您可以为整个查询表达式加引号并编写<@ query { .. } @>-这将无法直接工作,但是您可以将引号引出并提取查询的实际正文,然后将其直接传递给query.Run.这是适用于以上示例的示例:

With a bit more effort, it is actually possible to use the query { .. } syntax again. You can quote the entire query expression and write <@ query { .. } @> - this will not directly work, but you can then take the quotation and extract the actual body of the query and pass it to query.Run directly. Here is a sample that works for the above example:

open System.Linq open Microsoft.FSharp.Quotations open Microsoft.FSharp.Quotations.Patterns let runQuery (q:Expr<IQueryable<'T>>) = match q with | Application(Lambda(builder, Call(Some builder2, miRun, [Quote body])), queryObj) -> query.Run(Expr.Cast<Microsoft.FSharp.Linq.QuerySource<'T, IQueryable>>(body)) | _ -> failwith "Wrong argument" let test () = <@ query { for p in db.Products do where ((%predicate) p) select p.ProductName } @> |> runQuery |> Seq.iter (printfn "%s")

更多推荐

如何在F#中组成查询表达式?

本文发布于:2023-11-17 03:09:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1608598.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:表达式   如何在

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!