Question BindingNavigator and DBConcurenncyException

lacja

Member
Joined
Dec 10, 2011
Messages
6
Programming Experience
Beginner
Hi,

I'm using a bindingnavigator and having problem when I click my save button.
In fact, the problem appears when I click it twice.

First I click the ADD button. Fields get blanked.
I change a field and then click SAVE. Seems to work fine.

Then I change another value and click save again. I get an error (DBConcurenncyException) that tells me that UpdateCommand affects 0 record

I think but don't know how to solve it, that I'm no longer on my current record


Here is the SAVE button code
Private Sub BindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BindingNavigatorSaveItem.Click
Me.Validate()
Me.EvaluationsBindingSource.EndEdit()
Me.EvaluationsTableAdapter.Update(QA_DSEvaluation.Evaluations)

End Sub


 
Can you post the update command in the EvaluationsTableAdapter? You can find it in the dataset, properties of the TA
 
This?

<CommandText>UPDATE `Evaluations` SET `Matricule` = ?, `DateJour` = ?, `NoLot` = ?, `DateEvaluation` = ?, `DateAppel` = ?, `PosteRAO` = ?, `Reponse1` = ?, `Reponse2` = ?, `Reponse3` = ?, `Reponse4` = ?, `Reponse5` = ?, `Reponse6` = ?, `Notes1` = ?, `Reponse7` = ?, `Reponse8` = ?, `Reponse9` = ?, `Reponse10` = ?, `Reponse11` = ?, `Reponse12` = ?, `Reponse13` = ?, `Reponse14` = ?, `Notes2` = ?, `Reponse15` = ?, `Reponse16` = ?, `Reponse17` = ?, `Reponse18` = ?, `Reponse19` = ?, `Reponse20` = ?, `Notes3` = ?, `Reponse21` = ?, `Reponse22` = ?, `Reponse23` = ?, `Reponse24` = ?, `Reponse25` = ?, `Reponse26` = ?, `Reponse27` = ?, `Notes4` = ?, `Reponse28` = ?, `Reponse29` = ?, `Reponse30` = ?, `Reponse31` = ?, `Reponse32` = ?, `Reponse33` = ?, `Reponse34` = ?, `Notes5` = ?, `NotesGenerales` = ?, `HeureAppel` = ?, `DureeAppel` = ?, `HeureInscription` = ?, `CarteAppel` = ?, `idTypeAppel` = ?, `idFile` = ?, `DebutEvaluation` = ?, `FinEvaluation` = ? WHERE ((`idEval` = ?) AND ((? = 1 AND `Matricule` IS NULL) OR (`Matricule` = ?)) AND ((? = 1 AND `DateJour` IS NULL) OR (`DateJour` = ?)) AND ((? = 1 AND `NoLot` IS NULL) OR (`NoLot` = ?)) AND ((? = 1 AND `DateEvaluation` IS NULL) OR (`DateEvaluation` = ?)) AND ((? = 1 AND `DateAppel` IS NULL) OR (`DateAppel` = ?)) AND ((? = 1 AND `PosteRAO` IS NULL) OR (`PosteRAO` = ?)) AND ((? = 1 AND `Reponse1` IS NULL) OR (`Reponse1` = ?)) AND ((? = 1 AND `Reponse2` IS NULL) OR (`Reponse2` = ?)) AND ((? = 1 AND `Reponse3` IS NULL) OR (`Reponse3` = ?)) AND ((? = 1 AND `Reponse4` IS NULL) OR (`Reponse4` = ?)) AND ((? = 1 AND `Reponse5` IS NULL) OR (`Reponse5` = ?)) AND ((? = 1 AND `Reponse6` IS NULL) OR (`Reponse6` = ?)) AND ((? = 1 AND `Reponse7` IS NULL) OR (`Reponse7` = ?)) AND ((? = 1 AND `Reponse8` IS NULL) OR (`Reponse8` = ?)) AND ((? = 1 AND `Reponse9` IS NULL) OR (`Reponse9` = ?)) AND ((? = 1 AND `Reponse10` IS NULL) OR (`Reponse10` = ?)) AND ((? = 1 AND `Reponse11` IS NULL) OR (`Reponse11` = ?)) AND ((? = 1 AND `Reponse12` IS NULL) OR (`Reponse12` = ?)) AND ((? = 1 AND `Reponse13` IS NULL) OR (`Reponse13` = ?)) AND ((? = 1 AND `Reponse14` IS NULL) OR (`Reponse14` = ?)) AND ((? = 1 AND `Reponse15` IS NULL) OR (`Reponse15` = ?)) AND ((? = 1 AND `Reponse16` IS NULL) OR (`Reponse16` = ?)) AND ((? = 1 AND `Reponse17` IS NULL) OR (`Reponse17` = ?)) AND ((? = 1 AND `Reponse18` IS NULL) OR (`Reponse18` = ?)) AND ((? = 1 AND `Reponse19` IS NULL) OR (`Reponse19` = ?)) AND ((? = 1 AND `Reponse20` IS NULL) OR (`Reponse20` = ?)) AND ((? = 1 AND `Reponse21` IS NULL) OR (`Reponse21` = ?)) AND ((? = 1 AND `Reponse22` IS NULL) OR (`Reponse22` = ?)) AND ((? = 1 AND `Reponse23` IS NULL) OR (`Reponse23` = ?)) AND ((? = 1 AND `Reponse24` IS NULL) OR (`Reponse24` = ?)) AND ((? = 1 AND `Reponse25` IS NULL) OR (`Reponse25` = ?)) AND ((? = 1 AND `Reponse26` IS NULL) OR (`Reponse26` = ?)) AND ((? = 1 AND `Reponse27` IS NULL) OR (`Reponse27` = ?)) AND ((? = 1 AND `Reponse28` IS NULL) OR (`Reponse28` = ?)) AND ((? = 1 AND `Reponse29` IS NULL) OR (`Reponse29` = ?)) AND ((? = 1 AND `Reponse30` IS NULL) OR (`Reponse30` = ?)) AND ((? = 1 AND `Reponse31` IS NULL) OR (`Reponse31` = ?)) AND ((? = 1 AND `Reponse32` IS NULL) OR (`Reponse32` = ?)) AND ((? = 1 AND `Reponse33` IS NULL) OR (`Reponse33` = ?)) AND ((? = 1 AND `Reponse34` IS NULL) OR (`Reponse34` = ?)) AND ((? = 1 AND `HeureAppel` IS NULL) OR (`HeureAppel` = ?)) AND ((? = 1 AND `DureeAppel` IS NULL) OR (`DureeAppel` = ?)) AND ((? = 1 AND `HeureInscription` IS NULL) OR (`HeureInscription` = ?)) AND ((? = 1 AND `CarteAppel` IS NULL) OR (`CarteAppel` = ?)) AND ((? = 1 AND `idTypeAppel` IS NULL) OR (`idTypeAppel` = ?)) AND ((? = 1 AND `idFile` IS NULL) OR (`idFile` = ?)) AND ((? = 1 AND `DebutEvaluation` IS NULL) OR (`DebutEvaluation` = ?)) AND ((? = 1 AND `FinEvaluation` IS NULL) OR (`FinEvaluation` = ?)))</CommandText>
 
Yep, it helps explain what I say next..

DB Concurrency exceptions occur because this huge where clause causes 0 records to be found:

an update really only needs the primary key to work.. UPDATE table SET field = value WHERE primary_key = some_pk

But all that extra junk in the where clause is checking that all the values in the table are the same as when the data was downloaded

Suppose you download:

Select name, age, address From Person Where Name = 'john'

You get:
john, 23, NULL

Now suppose somewhere else in code or in another app on another machine, age is updated to 24

Your query, with all the junk in the where clause will be:

UPDATE person SET age = 25 WHERE
name = 'John' and
((age is null and 0 = 1) or age = 23) and
((address is null and 1 = 1) or (address = null)

let us explain why this complex IS NULL part comes:

((field IS NULL and ? = 1) or field = ?)
In this, the first ? parameter is set to the result of "If ORIGINAL value is null set parameter = 1 else 0"
and the second ? parameter is set to the ORIGINAL value that was downloaded.

Thus if you originally downloaded a null (which cannot be compared with =, hence the "if" part) this part of the clause evaluates to TRUE, and we have checked that a field that was null when it was downloaded is still null now

For fields that had a value when we downlaoded them, it is the other part that checks they are still the same value.. the field = ? part


Consider our person example again:
((age is null and 0 = 1) or age = 23) and

This is the part of the where clause that is FALSE, and causes 0 records to update. Age has a value.. it was 23 when we downlaoded it.. Someone else changed it to 24, and now we're falling over at the "or age = 23" part..

Thats why you get the concurrency exception.. you become aware that the data has changed since you downloaded it as a result of this excpetion.. You would then ordinarily solve it by presenting the user witha choice: keep theirs, overwrite theirs, attempt to merge..

The curious thing for you is why it's failing on your second save and you seem to assert that noone else (not your code, not a trigger, stored procedure, automatic anything) is changing your code.. Youre going to have to find out which column is causing the update to fail..
I recommend at the point you get the fail, in the catch handler for it use your tableadapter you download a new copy of the datatables and compare them:

VB.NET:
PrivateSub BindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BindingNavigatorSaveItem.Click
 Me.Validate()
 Me.EvaluationsBindingSource.EndEdit()
try
 Me.EvaluationsTableAdapter.Update(QA_DSEvaluation.Ev aluations)
 catch DbConcurrencyException
 dim dt as evaluationsdatatable = EvaluationsTableAdapter.GetData() 'or getdataby... if there are parameters to the select query

'lets see which original row value is mismatched
for each oldro as EvaluationsDataRow in QA_DSEvaluation.Evaluations
  Dim nuro as EvaluationsDataRow  = dt.FindByIDEVAL(oldro.IdEval)
  For Each dc as DataColumn in dt.Columns
    if oldro.Item(dc, DataRowVersion.Original) <> nuro.Item(dc) Then
      MsgBox(dc.ColumnName & " value differs on row with PK " & nuro.IdEval)
    End If
  Next dc 
End try
EndSub

The IF in my code might need a bit of work to cope with null values, but it's a start. Note it has been written without VB.NET so there may be minor syntax error or typos in names of classes, enums etc.. it's a pseudocode presentation of an idea only.. good luck!
 
Unfortunatly, it gives me an error when "oldro.Item(dc, DataRowVersion.Original)" is evaluated.

It answers me that column idEval does not belong to Evaluations table
 
I did say that that was pseudocode and would need tweaking a bit..

So does your Evaluations table contain an idEval column or not? Look at the table in the DataSet Viewer when debugging (point to the QA_DSEvaluation.Evaluations, wait for tooltip to appear, click magnifying glass)
 
can you post your project and I'll take a look. when you zip it up, delete the BIN and OBJ folders from the zip - i dont need them and they waste board storage space
 
Back
Top