schmoopy
schmoopy

Reputation: 6649

F# Async - An item with the same key has already been added

I am trying some async ops in f# but w/o much luck. I am trying to grab records from the db and perform operations on each record in Parallel.

let IsA1 companyId = 
    query {   for comp in db.Company do
                join cc in db.CC on (comp.CompanyId = int(cc.CompanyId))
                join pp in db.PP on (cc.PartId = pp.PartId)
                join tl in db.TL on (pp.CompanyId = tl.CompanyId)
                where (comp.CompanyId = companyId)
                select (comp.CompanyId > 0)
          }
          |> Seq.length |> fun len -> len > 0

let IsA2 companyId = 
    query {   for t in db.Title do
                join pp in db.PP on (t.Tid = pp.Tid)
                join comp in db.Company on (pp.CompanyId = comp.CompanyId)
                where (comp.CompanyId = companyId)
                select (comp.CompanyId > 0)
          }
          |> Seq.length |> fun len -> len > 0

let GetAffiliations id = 
    async {
        if (IsA1 id) then return "AffilBBB"
        elif (IsA2 id) then return "AffilCCD"
        else return Unknown
    }

let ProcessCompany (company:dbSchema.ServiceTypes.Company) =
    async {
            let grp = GetAffiliations company.CompanyId
            let result = { Id=company.CompanyId; Name=company.Name; Affiliations=grp; ContactType="ok"; }
            return result
    }

let GetCompanyNames =
    let companies = db.Company |> Seq.distinctBy(fun d -> d.CompanyId)
    companies
    |> Seq.map(fun co -> ProcessCompany co)
    |> Async.Parallel
    |> Async.RunSynchronously

When I run the above code, I get error:

System.ArgumentException: An item with the same key has already been added.

The error is occurring as a result of another function call inside async { }:

let grp = GetAffiliations company.CompanyId

I am sure its a newbie issue, but I am not sure what the issue is. I even tried making the call inside of the async{ } another async call and used let! grp = (GetAffiliations company.CompanyId) but that does not resolve.

Upvotes: 1

Views: 180

Answers (1)

hocho
hocho

Reputation: 1749

Because the two concurrent queries are sharing the same context, when the second result is added to the same context, you get an error saying that the context already has an item with the same key.

Using distinct instances of the 'db' context for each of the queries, should solve your issue.

Upvotes: 1

Related Questions