I have a sql table with a PK column ItemID
and unique index on column Value
.
CREATE TABLE [dbo].[Item](
[ItemID] [int] IDENTITY(1,1) NOT NULL,
[Value] [int] NULL
)
CREATE UNIQUE NONCLUSTERED INDEX [IDX_Item_Value_U_NC] ON [dbo].[Item]
(
[Value] ASC
)
I'm inserting multiple records (batch insert/update) in the table using linq-sql. I do an "exists" check before inserting the record.
void MultipleInserts(List<int> values)
{
using (var db = new DBDataContext())
{
foreach (var value in values)
{
var dbItem = db.Items
.Where(x => x.Value == value)
.SingleOrDefault();
if (dbItem == null)
{
var Item = new Item()
{
Value = value
};
db.Items.InsertOnSubmit(Item);
}
}
db.SubmitChanges();
}
}
I get the below exception due to the unique index if the list has the same values. Item
table has no records.
var values = new List<int>();
values.Add(1);
values.Add(1);
MultipleInserts(values);
Exception message:
Cannot insert duplicate key row in object 'dbo.Item' with unique index 'IDX_Item_Value_U_NC'.
The statement has been terminated.
How do I avoid this?
EDIT: I cannot do single inserts so I cannot move the db.SubmitChanges()
call inside the for loop.
EDIT2: The answers posted so far deal with fixing the data rather than a way within linq-sql. I have put a simple example with a list of ints. But in reality I have a list of object graph to inserts and every item hits multiple tables for insert/update. I found a way using linq DataContext
's ChangeSet
(DataContext.GetChangeSet().Deletes
, DataContext.GetChangeSet().Inserts
, etc.) which I have posted as answer.
The problem here is that you are inserting them both at the same time. Neither of them exist until you actually call db.SubmitChanges()
Try moving the db.SubmitChanges()
inside the loop and that should solve the problem.
ETA: Another possibility would be changing your loop from:
foreach (var value in values)
to
foreach (var value in values.Distinct())