Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Query Operators Fails at Runtime? #495

Closed
Thorium opened this issue Oct 21, 2016 · 1 comment
Closed

Custom Query Operators Fails at Runtime? #495

Thorium opened this issue Oct 21, 2016 · 1 comment
Labels

Comments

@Thorium
Copy link

Thorium commented Oct 21, 2016

I can extend QueryBuilder with custom operators, e.g.:

open System
open System.Linq
open Microsoft.FSharp.Linq

[<AutoOpen>]
module AsyncQueryBuilderOperations =

    type QueryBuilder with
        /// A query operator that returns the number of selected elements.
        [<CustomOperation("countAsync")>]
        member x.CountAsync(source:Linq.QuerySource<'T,'Q>) =
            source.Source.AsQueryable() |> getCountAsync

        /// A query operator that selects the first element from those selected so far.
        [<CustomOperation("headAsync")>]
        member x.HeadAsync(source:Linq.QuerySource<'T,'Q>) =
            source.Source.AsQueryable() |> getHeadAsync

        /// A query operator that selects the first element of those selected so far, or a default value if the sequence contains no elements.
        [<CustomOperation("headOrDefaultAsync")>]
        member x.HeadOrDefaultAsync(source:Linq.QuerySource<'T,'Q>) =
            async {
                let! res = source.Source.AsQueryable() |> getTryHeadAsync
                return match res with Some x -> x | None -> Unchecked.defaultof<'T>
            }

Then I can actually use them like:

[<Test >]
let ``simple select with countAsync``() =
    let dc = sql.GetDataContext()
    let query = 
        query {
            for cust in dc.Main.Customers do
            select cust.CustomerId
            countAsync
        } |> Async.RunSynchronously
    Assert.AreEqual(91, query)   

But the problem is that F# LINQ Query translator doesn't like them on runtime:

System.NotSupportedException : This is not a valid query expression. The 
method 'Microsoft.FSharp.Control.FSharpAsync`1[System.Int32] QueryBuilder.CountAsync
[String,Object](Microsoft.FSharp.Linq.QueryBuilder, Microsoft.FSharp.Linq.QuerySource`2
[System.String,System.Object])' was used in a query but is not recognized by the F#-to-LINQ query 
translator. Check the specification of permitted queries and consider moving some of the operations 
out of the query expression

at Microsoft.FSharp.Linq.QueryModule.TransInner(CanEliminate canElim, Boolean check, FSharpExpr immutQuery)
at Microsoft.FSharp.Linq.QueryModule.TransInnerAndCommit(CanEliminate canElim, Boolean check, FSharpExpr x)
at Microsoft.FSharp.Linq.QueryModule.TransInnerWithFinalConsume(CanEliminate canElim, FSharpExpr immutSource)
at Microsoft.FSharp.Linq.QueryModule.EvalNonNestedInner(CanEliminate canElim, FSharpExpr queryProducingSequence)
at Microsoft.FSharp.Linq.QueryModule.EvalNonNestedOuter(CanEliminate canElim, FSharpExpr tm)
at Microsoft.FSharp.Linq.QueryModule.clo@1737-1.Microsoft-FSharp-Linq-ForwardDeclarations-IQueryMethods-Execute[a,b](FSharpExpr`1 )
at QueryTests.simple select with countAsync() in C:\git\SQLProvider\tests\SqlProvider.Tests\QueryTests.fs:line 66

The problem is this file:

https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp/FSharp.Core/Query.fs

raise ... unsupportedQueryConstruct

@dsyme
Copy link
Collaborator

dsyme commented Oct 21, 2016

@Thorium Could you resubmit using the new issue template please? thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants