Reputation: 414
here I'm again for some help. :) I'm trying to insert data into my MySQL database using F#. My schema includes 3 tables (Experiments, Gene and Results):
Experiments | Results | Gene
Experiment id | Experiment id | Gene id
Experiment name | Gene id | Gene Name
| Value |
Now, I'm trying to add data into the db using SQLProvider.
let db = sql.GetDataContext()
let gene_tb = db.Vp32.Genes
let exp_tb = db.Vp32.Experiments
let results_tb = db.Vp32.Results
let createNewInput (genename: string) (expname: string) res =
let newRes = results_tb.Create()
let newGene = gene_tb.Create()
let newExp = exp_tb.Create()
newGene.GeneName <- genename
newExp.ExpName <- expname
newRes.ResultVal <- Some res
createNewInput "test1" "experiment_test1" (float32 999.5)
db.SubmitUpdates()
I'm having problems to make it understand that the result value is linked to the experiment and gene ids. It gives an error when I try to submit it: "Field 'Exp_id' doesn't have a default value". Well, there isn't a default value because it should be the ids of the other tables. Oh, and.. these IDs are set to auto increase. Moreover, everytime I add new data, if the experiment name exists already in the table, the id shouldn't increase. Do I have to do something like a 'trigger' for this or some specification code using 'if...then'?
Thank you very much in advance! :D Thanks to you I've already learned sooo much alredy, I can't believe! ^-^
SOLUTION: So, I found out that the problem was that I had to query the IDs of Experiments and Genes.. So I changed stuff a bit. For now I have 3 functions (one for each table) and the one for results do a small query before adding the result value:
let addNewExp (expname: string)=
let newExp = exp_tb.Create()
newExp.ExpName <- expname
db.SubmitUpdates()
let addNewGene (genename: string)=
let newGene = gene_tb.Create()
newGene.GeneName <- genename
db.SubmitUpdates()
let addNewRes (expName: string) (geneName: string) res =
let tempExpId =
query {
for experiment in exp_tb do
where (experiment.ExpName = expName)
select experiment.ExpId
}
|> Seq.head
let tempGeneId =
query {
for gene in gene_tb do
where (gene.GeneName = geneName)
select gene.GeneName
}
|> Seq.toArray |> String.concat ""
let newRes = results_tb.Create()
newRes.ExpId <- tempExpId
newRes.GeneId <- tempGeneId
newRes.ResultVal <- Some res
db.SubmitUpdates()
Indeed, it's necessary to do the query to get the id values before adding something in the associative table (results). Afterwards I just converted to the correct types (that are described in the database) since the query returns as sequence (Seq). I hope this can also help someone in the future.
Upvotes: 4
Views: 177
Reputation: 243061
I have not actually tried this, so it might not be right - but I think one strategy that should work would be to first insert the Experiment
record (with ExpName
) together with Gene
record with GeneName
.
When you then call SubmitUpdates
, the provider should insert the two records (which should work, because they have all the fields they need) and fill the Experiment id
and Gene id
properties of the inserted records.
You then have those IDs, so you should be abe to create a new Result
record with all the correct IDs, insert it and call SubmitUpdates
again.
(There might be a better way, but this could do the trick...)
Upvotes: 2