I insert data with LINQ to SQL on my DB on a table where there is a unique key on 2 columns.
When I try to insert a row with this unique key already inserted, I get:
Cannot insert duplicate key row in object 'dbo.613_LiveLove' with
unique index 'IX_613_LiveLove'. The duplicate key value is
(35715346455553, paul). The statement has been terminated.
I don't want this error message, just "LINQ to SQL, does not insert it" and continue the process.
Is there a way on doing this? Or need I to use try/catch?
This might help: http://msdn.microsoft.com/en-us/library/bb425822.aspx#linqtosql_topic18
"... any errors detected by the database will cause the submission process to abort and an exception will be raised. All changes to the database will be rolled back as if none of the submissions ever took place. The DataContext will still have a full recording of all changes so it is possible to attempt to rectify the problem and resubmit them by calling SubmitChanges() again..."
Use try catch. Catch the specific exception type, and throw your own exception (you propably want to create your own exception type) including your custom message. At the location in you code you want to continue the process, just catch that exception.
Related
I have a simple Linq dbml class, containing 1 table. First I have it configured to "Use runtime" to do the updates. Throgh the UI, I'm intentionally updating a column to a wrong value. Then calling dataContext.SubmitChanges throws an error, which is caught in a catch=block, showing a MessageBox "The UPDATE statement conflicted with the CHECK constraint ...", as it should. So, everything is fine.
Then I change the update behaviour to "Customize" and use a simple update stored procedure (just 1 simple update statement). Updating through the UI with correct values works like a charm. The update sproc is called and everything is fine. But when entering this wrong value through the UI, and then pressing update, I get an unhandled exception on this line of code (internal code of the Linq class):
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), field1, field2, ...);
Title: Exception User-Unhandled System.Data.SqlClient.SqlException:
'The UPDATE statement conflicted with the CHECK constraint
"CK_tblRitCentraal". The conflict occurred in database "RCS", table
"dbo.tblRitCentraal", column 'RitOpmerkingen'.
The statement has been terminated.'
Any help is greatly appreciated!
thanks for your reply. You are right, that my problem is, that the exception in yhe second case is not caught, even though it is exactly the same error as in the first case.
In the meantime I solved my problem. All I had to do was tick "do not break on this type of exceptions". Now the exception is nicely put through to the UI, and I can take care of it.
Still, I can't understand why. But hey, it got solved, so I shouldn't complain.
I have a table with primary key and I want to insert new record to that.
In my code, I check if record exists by exception. In the SQL stored procedure, I have insert code and surround by exception, in my application I execute that stored procedure and want to insert new record, if my record exist in table, insert code throws an error:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Sup_Item_Sup_Item_Cat". The conflict occurred in database test, table test. The statement has been terminated.
and goes to the catch block.
In my application I check the error that was returned by SQL, and it shows a message box to user that record is exist.
I want to know, is this way is Principles? or I must use if exist statement in SQL?
Exception should never be used when you can avoid it and return a value.
Exception is a "stress" on a system and much slower than any other way.
Its customary for a SP to return 0 if everything is Ok and a negative value if there is an error.
Either check your SP return code in application or use out parameter to determine problem. An error should be truly an error.
I'm using the EntityFramework BulkInsert extension to insert large datasets into my database. However, there is an AFTER INSERT trigger on the table that I'm inserting data into that doesn't seem to be firing. Is this a limitation of the extension or is there a way to ensure that the trigger fires when the operation completes?
It turns out I just wasn't looking hard enough. There are some overloads for the main BulkInsert method that are not listed anywhere in the documentation and I could not find them through any Google searches, but one of the overloads allow for flags. One of the flags is SqlBulkCopyOptions.FireTriggers.
It is used like: context.BulkInsert(values, SqlBulkCopyOptions.FireTriggers). Using this method, each row is processed individually by the trigger, and everything works as it should.
EDIT: Answer comment
can you explain what the CheckConstraint will do?
A constraint is when you add some checks such as the value must be between 10 and 50 to be valid and inserted.
So if you don't check constraint, a value of 5 will be inserted without a problem even if out of range. If you check constraint, an error will be throw:
The INSERT statement conflicted with the CHECK constraint "CHK_ColumnWithConstraint". The conflict occurred in database "db_2560", table "dbo.Customers", column 'ColumnWithConstraint'.
The statement has been terminated.
Here is an online example: https://dotnetfiddle.net/AMgTYQ
That's why I recommend SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints
If the table have a trigger, you probably when to fire them. If a column has a constraint, you probably want the operation to throw an error if the value is not valid with the check.
I am bulk inserting a long list of object.
than i execute a commit.
It fails sometimes with the error (C#)
"The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_MyFK". The conflict occurred in database "DCDCommunity", table
"MySchema.MyTable", column 'Id'.\r\nThe statement has been terminated."}
System.Exception {System.Data.SqlClient.SqlException}
Now, do I have to write a program that iterates on my data files to find the value or can I get it in the exception?
I can't answer "why?" but I can offer a suggestion - do some pre-checks to your data before doing a bulk insert to make sure foreign keys are valid, and whatever other data issues you might regularly face - like checking string lengths to avoid the "string or binary data would be truncated" error as mentioned in a comment.
I am pulling out my hair over here. I have a table that has a UNIQUE Key (IX_tblTable) and the unique key is on a column Number. I am parsing some data from the web and storing it in the table. My latest collection of data from the web contains number THAT ARE NOT CONTAINED IN THE DATABASE. so I am getting data from the site and all of the data I am getting in unique, there are no duplicates and the numbers in the list that is returned are not in the database.
I keep getting this error everytime I try to update the database, what is the best way to trap the error to see which number is throwing the error. I am storing everything that comes back in an object list and when it is done running I have 131 records that need to be inserted and I can not see which one is throwing this error. What is the bast way to trap it?
EDIT: I am using sql server 2005, wirtting in C# and using Linq2SQL. I can not post any c# code at this time for proprietary reasons...
Can you just disable your constraint for a while and see what duplicates save? Later you can remove duplicates and re-enable it.
Create a copy of the table without a primary key or uniqueness constraint (having the column, just not as a primary). Modify your code to insert into that table. Run it. Select values having more than one duplicate.
You can use an algorithm called binary search to find the 'wrong' data.
Suppose you have 131 lines of INSERT INTO ... VALUES(...) and you want to catch the one that's causing the error, you can divide your 131 lines into two pices(first 66 and last 65). Now run that 66 and 65 INSERTs separatelly, and see which throws the error. Continue to 'divide an try' until you get to one single line. (That's 10 tries in the worst case).
Are you controlling the lifecycle of your datacontext?
Insert 5
SubmitChanges (record inserted, no exception)
Insert 5
SubmitChanges (duplicateKeyException on 5)
Insert 6
SubmitChanges (duplicateKeyException on 5)
Why not use Begin Try... End Try.. Begin Catch... End Catch... in the SQL store procedure (I assume you use the SP to insert data) to capture the Row that causes the unique constraint violation?