Question

It's been a few days that I've been looking for a clean solution to this, but I am beginning to think it's not intended to be done by design, so I'm asking your opinion on the following.

I'll try to be short: I am using LINQ to SQL in C# to manipulate a table on a SQL server trough custom stored procedures as insert and update methods.

Since I am still a beginner with C#, i used the O-R Designer to create the DataContext class for me. Inside my code, i initialize a DataContext, retrieve data, perform necessary operations on it, and call the submitChanges() method to persist it to the database.

Everything goes fine, until an update or insert operation conflicts with a table constraint (e.g. I try to insert a duplicate value into a column with an UNIQUE constraint), resulting into an unhandled exception.

Unfortunately, the exception is not thrown by the submitChanges() method, which is the only one over which I have easy control (i.e. I can easily wrap it with try/catch and perform error handling staying in the same scope), it is instead thrown by the stored procedure call which is placed in a method inside the DataContext class from which i cannot access the resources I would like to use to handle the exception (e.g. the user interface)

From my previous readings, I assume the most popular scenario is preventing the exception to be thrown by implementing client-side validation, making the exception a rare and critical event which should not be recovered.

What i want to do instead is to delegate data validation to the SQL server, and in case of invalid data, handle the exception on the client side. (displaying an error)

Most programmers think for different reasons that this is a wrong aproach, but I'd like to know if it is possible in the first place. Can i handle the exception in a more practical way? Is there something I'm missing?

EDIT: To clarify better the problem, the exception is thrown in the following method

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="Contabilità.Cliente_modifica")]
        public int Cliente_modifica([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> id, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="VarChar(50)")] string nuovoNome)
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id, nuovoNome);
            return ((int)(result.ReturnValue));
        }

I Could wrap the call to the stored procedure in a try-catch statement as follows:

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="Contabilità.Cliente_modifica")]
        public int Cliente_modifica([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> id, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="VarChar(50)")] string nuovoNome)
        {
            IExecuteResult result = null;
            try
            {
                result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id, nuovoNome);
            }
            catch (Exception exc)
            {

            }
            return ((int)(result.ReturnValue));
        }

Which does work, but throws in turn another null pointer exception because the value of result doesn't get modified. In addition to this, from this scope i cannot access the graphic interface (which is instead accessible from the block where i call submitChanges() )

How do I handle (even if in an uncomfortable way) the exception in that method? Is there a way to handle it somwhere else?

No correct solution

OTHER TIPS

If you call your stored procedure inside a method, use a try/catch block.

In it throws some exception, it will jump to the catch and you will be able to do handle the exception, I don´t know, maybe throwing a message with the error, logging the error in a database or something ;)

Can you show the stored procedure? You may be able to do the insert/update logic within your LINQ to SQL code and simply call SubmitChanges() there, rather than handing it off to the stored procedure. This will provide immediate feedback regarding validation and success of the insert/update, which can then be passed back to the UI. I find this to be a much better method of inserting/updating unless I have a great deal of DB logic that really requires a stored procedure. You will want to make sure your input is parameterized to protect against SQL injection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top