I have a search type which is used to query the database as follows,
type UserSearch =
{ limit: int option
skip: int option }
I'm using SQLProvider
and would like to use limit
and skip
variables in my query such as
query {
for user in Db.getDataContext().MyDb.Users do
select user
// if searchParams.limit.IsSome then
// take searchParams.limit.Value
// if searchParams.skip.IsSome then
// skip searchParams.skip.Value
}
Is it possible?
My current approach is as follows;
let mutable search =
query {
for user in Db.getDataContext().MyDb.Users do
select user
}
if searchParams.limit.IsSome then
search <-
query {
for user in search do
select user
take searchParams.limit.Value
}
search |> Seq.toArray
Since queries are lazy, this should result a single query, am i correct on this assumption?
CodePudding user response:
Unfortunately, the query
builder turns the result into seq<_>
and forces it to run the SQL query, so you cannot easily compose queries this way. There may be more sophisticated tricks you could use, but for your specific case, it may be easier to just use a reasonable default value such as 0
for skip
and Int32.MaxValue
for take
:
query {
for user in Db.getDataContext().MyDb.Users do
skip (defaultArg searchParams.skip 0)
take (defaultArg searchParams.limit.Value Int32.MaxValue)
select user }
This will generate a query with skip
and take
even when you do not need that, which may have some performance implications - I do not think it matters, but it may be best to test that.