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

Correct way to create reusable queries #108

Open
AP-Hunt opened this issue Sep 14, 2024 · 0 comments
Open

Correct way to create reusable queries #108

AP-Hunt opened this issue Sep 14, 2024 · 0 comments

Comments

@AP-Hunt
Copy link

AP-Hunt commented Sep 14, 2024

Hi folks,

I've got an interface to implement with methods like

GetById(id) : User
GetByName(name): User
GetByEmail(email) : User
GetByPhoneNumber(phoneNo): User

An implementation for any one of these might look like below, and each of them varies only in the where clause.

member this.GetById(id: string) =
    conn.SelectAync<User> <| select {
        from u in usersTable
        where (u.Id = id)
    }

I tried to write a small reusable function (below) to tidy things up, but I got a NotImplementedException from LinqExpressionVisitors.visitWhere on line 260

Relevant stack trace

Dapper.FSharp.SQLite.LinqExpressionVisitors.visit$cont@243-4(FSharpFunc<MemberInfo, string> qualifyColumn, Expression exp, BinaryExpression x, Unit unitVar) in C:\Dzoukr\Personal\Dapper.FSharp\src\Dapper.FSharp\SQLite\LinqExpressionVisitors.fs
Dapper.FSharp.SQLite.LinqExpressionVisitors.visit@200-30(FSharpFunc<MemberInfo, string> qualifyColumn, Expression exp) in C:\Dzoukr\Personal\Dapper.FSharp\src\Dapper.FSharp\SQLite\LinqExpressionVisitors.fs
Dapper.FSharp.SQLite.LinqExpressionVisitors.visitWhere<T>(Expression<Func<T, bool>> filter, FSharpFunc<MemberInfo, string> qualifyColumn) in C:\Dzoukr\Personal\Dapper.FSharp\src\Dapper.FSharp\SQLite\LinqExpressionVisitors.fs
Dapper.FSharp.SQLite.Builders+SelectExpressionBuilder<T>.Where(QuerySource<T> state, Expression<Func<T, bool>> whereExpression) in C:\Dzoukr\Personal\Dapper.FSharp\src\Dapper.FSharp\SQLite\Builders.fs

let findFirstBy<'t when 't: null> (conn: DbConnection) (tbl: QuerySource<'t>)  (expr: 't -> bool) =
    task {
        let xs! = conn.SelectAsync<'t> <| select {
            for x in tbl do
            where (expr x)
        }
        
        match Seq.length xs with
        | 0 -> return null
        | _ -> return Seq.head xs        
    }
    
...

member this.GetById(id: string) = findFirstBy conn usersTable (fun u -> u.Id = id)
member this.GetByName(name: string) = findFirstBy conn usersTable (fun u -> u.Name = name)

What would be the correct way of implementing this? Or am I pursuing something that Dapper.FSharp wasn't designed to support?

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

No branches or pull requests

1 participant