SqlDataProvider - Составьте предложение where динамически и выполните команду - PullRequest
1 голос
/ 22 сентября 2019

У меня есть следующее требование:

Запрос таблицы SQL с динамически сгенерированным оператором where, который должен быть составлен из списка во время выполнения.

[<Literal>]
let connectionString = "Data Source=..."

type sql = SqlDataProvider< 
                  ConnectionString = connectionString,
                  DatabaseVendor = Common.DatabaseProviderTypes.MSSQLSERVER,
                  UseOptionTypes = true>
let ctx = sql.GetDataContext()

type Key = {k:string;v:string}

let findCustomersByKeys (keys:Key list) =
    query{
         for c in ctx.Dbo.Customers do
         where (keys.Any(fun k -> c.k = k.k && c.v = k.v))//this is what i wish i could do
         select c
    }

Есть ли способсделать это в F # с SqlDataProvider?Любая другая техника?

1 Ответ

4 голосов
/ 22 сентября 2019

Вы можете использовать кавычки для динамического построения предиката и склеивания его непосредственно в выражения запроса, поскольку выражения запроса фактически скомпилированы в сами цитаты.

Предикат создается путем сворачиванияключи, рекурсивно соединяющие или-условия на начальное условие false.Но поскольку мы не можем закрыть здесь c, нам также нужно обернуть каждое условие в функции и пропустить аргумент через цепочку предикатов.

open Microsoft.FSharp.Quotations

type Key = {k:string;v:string}

let findCustomersByKeys (keys:Key list) =
    let predicate = 
        keys
            |> List.fold
                (fun (acc: Expr<Key -> bool>) k ->
                    <@ fun c -> (%acc) c || c.k = k.k && c.v = k.v @>)
                <@ fun c -> false @>

    query {
         for c in ctx.Dbo.Customers do
         where ((%predicate) c)
         select c
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...