F# Powerpack and Entity Framework: How refactor a common part of two queries

169 views Asked by At

I have two queries:

 member private x.CheckIfUserExistsUsingId(userId:int, context:StoryBoardContext) =
  <@ context.Users 
     |> Seq.exists (fun currentUser -> currentUser.Id = userId) @>

And

member private x.FindUserById(userId:int, context:StoryBoardContext) =
 <@ context.Users 
    |> Seq.filter(fun currentUser -> currentUser.Id = userId) 
    |> Seq.head @>

I'd like to refactor this so that the two

 fun currentUser -> currentUser.Id = userId

Can be one method like:

member private x.IfUserIdMatches (userId:int) = 
  fun (currentUser:User) -> currentUser.Id = userId

And then use it:

member private x.CheckIfUserExistsUsingId(userId:int, context:StoryBoardContext) =
  <@ context.Users 
     |> Seq.exists (x.IfUserIdMatches (userId)) @>

But I keep getting an error:

The following construct was used in query but is not recognised by the F#-to-LINQ query translator...

Which makes me think my signature for the method is poorly constructed. Being new to F# it has me a little confused since I'm positive this can be done in C# using a method that returns a Func. However, I understand that there are differences right off the bat since F# is using a different library to construct linq queries.

1

There are 1 answers

2
Daniel On BEST ANSWER

Does it work if you change your method to return Expr

member private x.IfUserIdMatches (userId:int) = 
  <@ fun (currentUser:User) -> currentUser.Id = userId @>

and use splicing?

member private x.CheckIfUserExistsUsingId(userId:int, context:StoryBoardContext) =
  <@ context.Users 
      |> Seq.exists %(x.IfUserIdMatches (userId)) @>