我有一组函数使用FSharp.Data.TypeProviders通过sql对数据库进行多次调用来检索数据。
代码如下所示:
let query_one (firstName:string) (lastName:string) =
query { for a in db.Names do
where (a.firstname = FirstName && a.secondname = LastName)
select a } |> Seq.last
let query_two (jobTitle:string) =
query { for a in db.Jobs do
where (a.jobId = jobTitle)
select a } |> Seq.last
let detailsList = new List<('a*'b)>()
let queries =
workerDetails
|> Array.Parallel.map (fun (firstn, lastn, jobt) ->
let j1 = query_one firstn lastn
let j2 = query_two jobt
detailsList.add (j1,j2) )
当我运行时,我得到以下内容:
发生了'System.ArgumentException'类型的第一次机会异常 在FSharp.Core.dll
中附加信息:具有相同密钥的项目已经存在 加入。
更确切地说:
System.ArgumentException:具有相同键的项已经存在 添加。在 Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation(FSharpExpr 吃 Microsoft.FSharp.Linq.QueryModule.EvalNonNestedInner(CanEliminate canElim,FSharpExpr queryProducingSequence)at Microsoft.FSharp.Linq.QueryModule.EvalNonNestedOuter(CanEliminate canElim,FSharpExpr tm)at Microsoft.FSharp.Linq.QueryModule.clo@1737-1.Microsoft-FSharp-Linq-ForwardDeclarations-IQueryMethods-Execute [A,B](FSharpExpr`1 ) ... ... 在 Microsoft.FSharp.Collections.ArrayModule.Parallel.Map@714-3.Invoke(的Int32 obj)at System.Threading.Tasks.Parallel&LT;&GT; c__DisplayClassf`1.b__c() 在System.Threading.Tasks.Task.InnerInvoke()at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)at at System.Threading.Tasks.Task&LT;&GT; c__DisplayClass11.b__10(对象 参数0)&LT; ---
我也尝试使用Parallel.For()从C#运行它。我可能遗漏了一些基本的东西。有一种简单的方法可以使函数线程安全吗?或查询表达式?
感谢您的帮助!
可能的解决方案: 当我在函数中包含对数据库上下文的调用时解决了parralel异常。如:
let query_one (firstName:string) (lastName:string) =
let db = temp_schema.GetDataContext()
query { for a in db.Names do
where (a.firstname = FirstName && a.secondname = LastName)
select a } |> Seq.last