Я хочу передать большой объем данных из F # в таблицу SQL. В основном мой код F # создает матрицу из трех столбцов ( UserID, ProductID and price
) и N строк. Я хотел бы «скопировать / pate it» в базу данных. Я попробовал несколько опций, но в конце передача данных из F # очень медленная (около одного часа для 10000 строк).
Благодаря ответам на предыдущий вопрос. Как включить хранимую процедуру в F # , интересным способом решения этой проблемы является использование SqlBulkCopy
.
SqlBulkCopy
требует тип базы данных для своего метода WritetoServer
но я не нашел никакого существующего кода или простого способа преобразования матрицы в базу данных. У вас есть предложения или идеи?
Это должно помочь вам (и SqlBulkCopy
к документации для получения дополнительной информации о SqlBulkCopy
):
//you must reference System.Data and System.Xml
open System.Data
open System.Data.SqlClient
let bulkLoadUserPurchases (conn:SqlConnection) (userPurchases: list<int * int * float>) =
use sbc = new SqlBulkCopy(conn, SqlBulkCopyOptions.TableLock, null, BatchSize=500, BulkCopyTimeout=1200, DestinationTableName="YOUR_TABLE_NAME_HERE")
sbc.WriteToServer(
let dt = new DataTable()
["UserID", typeof<int>
"ProductID", typeof<int>
"Price", typeof<float>]
|> List.iter (dt.Columns.Add>>ignore)
for userPurchase in userPurchases do
let userId, productId, price = userPurchase
let dr = dt.NewRow()
dr.["UserID"] <- userId
dr.["ProductID"] <- productId
dr.["Price"] <- price
dt.Rows.Add(dr)
dt)
Если у вас все в порядке со сторонними библиотеками, fastmember может быть очень полезен здесь.
module DB =
open System.Data
open System.Data.SqlClient
open FastMember
// val bulk : conn:SqlConnection -> table:string -> columns:seq<string*string> -> items:seq<a'>
let bulk conn table columns items =
use bcp = new SqlBulkCopy(connection = conn)
bcp.EnableStreaming <- true
bcp.DestinationTableName <- table
for n,v in columns do
bcp.ColumnMappings.Add(new SqlBulkCopyColumnMapping(sourceColumn = n, destinationColumn = v))
|> ignore
bcp.WriteToServer(items |> ObjectReader.Create)
Это оставляет вам универсальный метод, в который вы можете просто направить любой seq<a'>
. Наряду с некоторыми параметрами конфигурации, которые вы, конечно, можете настроить в соответствии со своими потребностями.