我想将大量数据从F#传输到SQL表。基本上我的F#代码创建了一个包含三列(UserID, ProductID and price
)和N行的矩阵。我想“复制/掌握它”到数据库中
我尝试了几种选择,但最后,F#的数据传输速度非常慢(10000行左右大约一小时)。
感谢上一个问题How to include a stored procedure in F#的答案,解决此问题的有趣方法是使用SqlBulkCopy
。
SqlBulkCopy
需要其WritetoServer
方法的数据库类型,但我没有找到任何现有代码或将矩阵转换为数据库的简单方法。
你有什么建议或想法吗?
答案 0 :(得分:5)
这可以帮助您入门(并参考documentation了解有关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)
答案 1 :(得分:1)
如果您对第三方库没什么意见,那么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'>
引入其中。连同一些配置参数,您当然可以根据需要进行配置。