Thanks Ben,I begin to understand... here is the SQL command really sent by the BO (concurrency mode set on allfields, so all the additional WHERE clauses are correct):
DELETE FROM [dbo].[cuves] WHERE [cuve_pk] = @cuve_pk AND (([numcuve] = @numcuve_ORG) OR ((@numcuve_ORG IS NULL) AND ([numcuve] IS NULL))) AND (([qtestock] = @qtestock_ORG) OR ((@qtestock_ORG IS NULL) AND ([qtestock] IS NULL))) AND (([volumax] = @volumax_ORG) OR ((@volumax_ORG IS NULL) AND ([volumax] IS NULL))) AND (([dispo] = @dispo_ORG) OR ((@dispo_ORG IS NULL) AND ([dispo] IS NULL))) AND (([directe] = @directe_ORG) OR ((@directe_ORG IS NULL) AND ([directe] IS NULL)));
@volumax_ORG was 10 on A client side when BO was filled, and User B upadated its related field to 100 before A asked for deletion.
So my SQL command would never raise an exception, since there was no line matching on the server!
I totally misunderstood the purpose of DeleteConcurrencyType, wich is only to add the additional where clauses, right?
How could I retrieve the result of the delete command (boolean or #line deleted) without writing a specific procedure?
Or is it a better practice to create a property "is_deletabled" on my BO class, and to check in beforedelete method to switch that property to True or False, so it could be retrieved by beforedelete methode on UI layer?
and the SetDebugOn is really a very nice tool 