我有一组函数,它们使用 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) )
当我运行它时,我得到以下信息:
FSharp.Core.dll 中出现“System.ArgumentException”类型的第一次机会异常
附加信息:已添加具有相同密钥的项目。
更准确地说:
System.ArgumentException:已添加具有相同键的项目。在 Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation(FSharpExpr e) 在 Microsoft.FSharp.Linq.QueryModule.EvalNonNestedInner(CanEliminate canElim, FSharpExpr queryProducingSequence) 在 Microsoft.FSharp.Linq.QueryModule.EvalNonNestedOuter(CanEliminate canElim, FSharpExpr tm)在 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) 在 System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.b__c() 在 System.Threading.Tasks.Task.InnerInvoke() 在 System.Threading.Tasks System.Threading 中的 .Task.InnerInvokeWithArg(Task childTask)。
我还尝试使用 Parallel.For() 从 C# 运行它。我可能缺少一些基本的东西。有没有一种简单的方法可以使函数线程安全?还是查询表达式?
谢谢您的帮助!
解决的可能选项:当我在函数中包含对数据库上下文的调用时,解决了并行异常。如:
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