1

I am a beginner in c# .NET and I am struggling to find an efficient way to catch an unique constraint exception in c# (windows forms).

I am dealing with a combination of three database table columns that are supposed to be unique but I am unable to handle the arising exception on my form.

The code that I am trying on the OnBeforeSaving Event of my database manager is attached below. Thanks in advance for the help. I am looking for an efficient way to catch the exception(Oracle).

private void dbInstCharges_OnBeforeSaving(object sender, DataManagerSaveArgs e)
{
    try
    {
        this.dbInstCharges.Table.PrimaryKey = new DataColumn[] { dbInstCharges.Table.Columns["EQ17_GC09_ID"], dbInstCharges.Table.Columns["EQ17_CH01_ID"], dbInstCharges.Table.Columns["EQ17_GC05_ID"] };
    }
    catch (ConstraintException ex)
    {
        MessageBox.Show(ex.Message);
    }

The updated block of code is

        private void dbInstCharges_OnBeforeSaving(object sender, DataManagerBeforeSavingArgs e)
       {
        //e.Record["EQ17_SS01_ID"] = Config.MemberID;
        //e.Record["EQ17_EQ16_ID"] = dbManager.CurrentDataRecord["EQ16_ID"];
        try
        {
            UniqueConstraint TableUnique = new UniqueConstraint (new DataColumn[] { dbInstCharges.Table.Columns["EQ17_GC09_ID"], dbInstCharges.Table.Columns["EQ17_CH01_ID"], dbInstCharges.Table.Columns["EQ17_GC05_ID"] });
            dbInstCharges.Table.Constraints.Add(TableUnique);
            //this.dbInstCharges.Table.PrimaryKey = new DataColumn[] { dbInstCharges.Table.Columns["EQ17_GC09_ID"], dbInstCharges.Table.Columns["EQ17_CH01_ID"], dbInstCharges.Table.Columns["EQ17_GC05_ID"] };
        }
        catch (Exception ex)
        {
            MessageBox.Show("Please enter a unique record");

        }
      }

Code after handling the ArgumentException.

    private void dbInstCharges_OnBeforeSaving(object sender, DataManagerBeforeSavingArgs e)
    {
        //e.Record["EQ17_SS01_ID"] = Config.MemberID;
        //e.Record["EQ17_EQ16_ID"] = dbManager.CurrentDataRecord["EQ16_ID"];
        try
        {

            UniqueConstraint TableUnique = new UniqueConstraint(new DataColumn[] { dbInstCharges.Table.Columns["EQ17_GC09_ID"], dbInstCharges.Table.Columns["EQ17_CH01_ID"], dbInstCharges.Table.Columns["EQ17_GC05_ID"], dbInstCharges.Table.Columns["EQ17_SS01_ID"], dbInstCharges.Table.Columns["EQ17_EQ16_ID"] });
            dbInstCharges.Table.Constraints.Add(TableUnique);
            //this.dbInstCharges.Table.PrimaryKey = new DataColumn[] { dbInstCharges.Table.Columns["EQ17_GC09_ID"], dbInstCharges.Table.Columns["EQ17_CH01_ID"], dbInstCharges.Table.Columns["EQ17_GC05_ID"], dbInstCharges.Table.Columns["EQ17_SS01_ID"], dbInstCharges.Table.Columns["EQ17_EQ16_ID"] };
        }
        catch (ArgumentException ex)
        {
            MessageBox.Show("Please enter a unique record");
        }

    }
Hamza Shakeel
  • 11
  • 1
  • 3
  • Welcome to StackOverflow! It's not really clear to me: does the code shown catch the exception and you're asking what to do with it? Or is the exception thrown somewhere else? Then please show the code that throws it. I guess it's not thrown "On_Before_Saving" but when actually really saving the data. btw: you're talking about `OnBeforeSaving` but the method shown is named `..._OnDataSaved`... typo or part of the bug? – René Vogt Jan 02 '17 at 13:43
  • http://stackoverflow.com/questions/24740376/best-way-to-catch-sql-unique-constraint-violations-in-c-sharp-during-inserts Looks like duplicate question. – saTech Jan 02 '17 at 13:44
  • What is the problem with this code? – Renatas M. Jan 02 '17 at 13:50
  • @Reniuz it catches the primary key constraint but it still does not catch the unique constraint exception. Any of the columns can have null values but it gives an error "ColumnName does not allow nulls". Is there any other way to make these columns unique other than the way i have tried? – Hamza Shakeel Jan 02 '17 at 14:02
  • Have you tried to change `ConstraintException` to `Exception` and check while debugging what type of exception you getting? You might get `OracleException` which contains error code in it. And the error code you should check should be `1` (which probably stands for ORA-00001). – Renatas M. Jan 02 '17 at 14:21
  • [Custom validation unique property](https://stackoverflow.com/questions/32172157/c-sharp-custom-validation-unique-property-generic-classes) – Reza Aghaei Jan 02 '17 at 15:08
  • @Reniuz changing ConstraintException to Exception catches the argument exception in the current scenario but the unique constraint exception is still there. I guess there must be another way to make these columns unique in the code which i am not getting to. – Hamza Shakeel Jan 03 '17 at 06:05
  • @Reniuz http://stackoverflow.com/questions/28336955/how-to-handle-unique-constraint-exception-in-datatable-while-adding-record-in-c Probably this is something that i was looking for? – Hamza Shakeel Jan 03 '17 at 06:20
  • Then first question is why you getting argument exception? It is really difficult to say whats going on without debugging. – Renatas M. Jan 03 '17 at 07:49
  • @Reniuz I have debugged and it still catches the argument exception instead of the unique constraint exception. – Hamza Shakeel Jan 03 '17 at 09:39
  • can you add the exception details in your question? – Renatas M. Jan 03 '17 at 10:06
  • If the Argument Exception occurs before your Unique Constrain Exception the Argument Exception is catched for sure. Fix your ArgumentException or extend your catch-Block. catch (ArgumentException ex) {}catch(OracleException ex) So you can handle the specific ArgumentException and all OracleExceptions differently. – Sebi Jan 03 '17 at 10:57
  • @Sebi But the scenario demands the unique constraint exception to be caught rather than the argument exception. With the code update and having a unique data column as a constraint it should catch the unique constraint and not the argument exception. – Hamza Shakeel Jan 03 '17 at 11:23
  • @HamzaShakeel Why it shouldn't catch the ArgumentException? You just catch all Exceptions with catch (Exception). If an ArgumentException occurs in your code this will be catched. It will just catch the first exception that occurs. I don't see any reason in your code why an ArgumentException shouldn't be thrown or catched. – Sebi Jan 03 '17 at 11:30
  • @Sebi I think the code needs to be altered in order for the unique constraint exception to be thrown because the concerning part is to catch the unique constraint. – Hamza Shakeel Jan 03 '17 at 11:42
  • @HamzaShakeel Your code will catch the UniqueContraintException if no other Exception occur before. So your code is right in this point. Your problem is if you don't handle the argument Exception you will never reach the point where you can handle the UniqueContraintException. – Sebi Jan 03 '17 at 12:10
  • @Sebi I have handled the argument Exception by throwing an exception message. It manages the argument Exception but after that the control never goes into the catch block where I am trying to catch the UniqueConstraintException (ConstraintException exception){}. – Hamza Shakeel Jan 03 '17 at 12:14
  • @HamzaShakeel Can you please update your question and post the code include the handling of your ArgumentException. – Sebi Jan 03 '17 at 12:16
  • @HamzaShakeel What are the details (message, part of stack trace etc.) of argument exception? I think you getting constraint unrelated things. – Renatas M. Jan 03 '17 at 12:44
  • FYI you can do like this: `try{...}catch(ConstrainException constrainError){ handle constraint error }catch(Exception upsYouHaveOtherTypeOfError) { handle any other possible error }` – Renatas M. Jan 03 '17 at 14:55

1 Answers1

1

I think you don't really understand Exception-Handling. I will try to explain your fault/missunderstanding as answer. If you execute a block of code this code runs up to the point where an exception occurs or it completes. If an exception occurs your code break and throw the exception or executes the catch-block if it exists one. If you use a try{} catch{} structure and an exception occurs, the code will following in catch{}. But there is no goto or jump back to your code in your try-block. What does this mean for your codeblock:

try
{
  UniqueConstraint TableUnique = new UniqueConstraint(new DataColumn[{//Your data});
  dbInstCharges.Table.Constraints.Add(TableUnique);
  //this.dbInstCharges.Table.PrimaryKey = new DataColumn[] {//Your data};
}
catch (ArgumentException ex)
{
  MessageBox.Show("Please enter a unique record");
}

The try-block is executed up to the point where the Argument-Exception occurs. Because you catch the ArgumentException (which is the right way), the code jumps to the catch-block and execute it. The Message is shown and your code is done. Make sure that after handling the exception the code doesn't jump back and execute further lines of your try-block. This won't and can't work because there is an wrong Argument which brokes your code. So it is absolutly nessesary that you fix your Argument-Exception. After fixing this issue you can handle your Unique-Constraint Exception as follows:

try
{
    UniqueConstraint TableUnique = new UniqueConstraint(new DataColumn[{//Your data});
  dbInstCharges.Table.Constraints.Add(TableUnique);
  //this.dbInstCharges.Table.PrimaryKey = new DataColumn[] {//Your data};
}
catch (OracleException ex)
{
  MessageBox.Show("Please enter a unique record.");
}

The ArgumentException always break your code before the code with your Unique-Constrain Exception is executed. That's why this exception is never catched.

Sebi
  • 3,879
  • 2
  • 35
  • 62