Я определил простой тип записи
type RowSapPL = { CargoID: int; Currency: string; IsInternal: bool; Amount: decimal}
, и у меня есть несколько функций, очищающих таблицу
let emptySapPl () =
asyncSeq {
try
let! dels =
query {
for pl in context.OilPhysical.SapPl do
where (true)
} |> Seq.``delete all items from single table``
return Ok (dels, "deleted")
with
| exc ->
return Error (exc.Message, "emptySapPl failed")
}
и вставляющих новые строки с помощью поставщика типа Sql.
let loadSapPL (rows:RowSapPL[]) : AsyncSeq<Result<int * string, string * string>> =
asyncSeq {
try
rows
|> Array.iter( fun r ->
context.OilPhysical.SapPl.``Create(Amount, CargoID, Currency, InternalCurr)`` (r.Amount, r.CargoID, r.Currency, r.IsInternal) |> ignore
)
do! context.SubmitUpdatesAsync()
return Ok (rows |> Array.length, "inserted")
with
| exc ->
return Error (exc.Message, "loadSapPL failed")
}
В заключение я предоставляю API, который обрабатывает записи в виде фрагментов
type DB() =
member x.loadSapPL (rows:RowSapPL[]) : AsyncSeq<Result<int * string, string * string>> =
asyncSeq {
yield! emptySapPl()
let chunks = rows |> Array.chunkBySize 500
for chunk in chunks do
yield! loadSapPL chunk
}
, и я делаю быстрый тест в F # интерактив
let action (res: Result<int * string, string * string>) =
async {
match res with
| Ok (i,m) -> printfn "*** Ok %d %s *** " i m
| Error (m,e) -> printfn "*** Error %s %s *** " m e
}
try
async {
let db = DB()
let rows = [|
{ CargoID = 1; Currency = "EUR"; IsInternal = true; Amount = 123.12m};
{ CargoID = 1; Currency = "USD"; IsInternal = false; Amount = 145.89m};
|]
printfn "starting async seq"
do! AsyncSeq.iterAsync action (db.loadSapPL rows)
printfn "async seq ended"
} |> Async.StartImmediate
with
| exc ->
printfn "Error %s " (exc.ToString())
Все тоже хорошос точки зрения БД (я вижу ожидаемые записи в таблице), но я не могу прочитать сообщения ("*** Ok ... "
) action
в консоли F # Interactive в Visual Studio. Я также пробовал с AsyncSeq.iter
вместо AsyncSeq.iterAsync
и синхронной версией action
. Что мне не хватает? Только "starting async seq"
и "async seq ended"
и журналирование sql (из тривиального SqlQueryEvent |> Event.add
, не показанного выше) печатаются из выражения асинхронного вычисления.