views:

84

answers:

2

Although this probably isn't best practice, I am trying to clear a series of records from a database table, and then insert a series of records - some of which may have been in the original series, and others which may be new. I'm using linqtosql in C#. Pseudo-code I have to do this is below; it fails with "Cannot add an entity with a key that is already in use."

using (dbDataContext context = new dbDataContext()
{
  // I've also tried using table.LinkedTable.Clear(); but that shows the same error
  while (table.LinkedTable.Count() > 0)
  {
    table.LinkedTable.RemoveAt(0);
  }

  foreach (ListItem item in SelectedItems.Items)
  {
    LinkedTable lt = new LinkedTable();
    lt.id = table.id;
    lt.SomeValue = item.SelectedValue;
    table.LinedTable.Add(lt);
  }
  context.SubmitChanges();
}

It seems like linqtosql is not taking note that I have removed items, before it tries to add items, causing a duplication error. Does anyone have any suggestions to correct this?

EDIT If I add a SubmitChanges after doing the deletes, I then end up with this message.

"An attempt was made to remove a relationship between a table and a LinkedTable. However, one of the relationship's foreign keys (LinkedTable.Id) cannot be set to null."

A: 

Looks like you're missing a call to .SubmitChanges() after removing the records you don't want.

For example (using your pseudo-code):

using (dbDataContext context = new dbDataContext()
{
  // I've also tried using table.LinkedTable.Clear(); but that shows the same error
  while (table.LinkedTable.Count() > 0)
  {
    table.LinkedTable.RemoveAt(0);
  }
  context.SubmitChanges();     // Submit the "removal" of records HERE!!!


  foreach (ListItem item in SelectedItems.Items)
  {
    LinkedTable lt = new LinkedTable();
    lt.id = table.id;
    lt.SomeValue = item.SelectedValue;
    table.LinedTable.Add(lt);
  }
  context.SubmitChanges();
}
CraigTP
+2  A: 

You could try to use the ITable.DeleteAllOnSubmit method:

using (dbDataContext context = new dbDataContext()
{
  // table.LinkedTable is a EntitySet of LinkedTable objects,
  // we remove from the "LinkedTable" table, the records that
  // are related to the "table" object:
  context.LinkedTable.DeleteAllOnSubmit(table.LinkedTable);

  foreach (ListItem item in SelectedItems.Items)
  {
    LinkedTable lt = new LinkedTable();
    lt.id = table.id;
    lt.SomeValue = item.SelectedValue;
    table.LinedTable.Add(lt);
  }
  context.SubmitChanges();
}
CMS
This works perfectly - though can anyone say *why* it does, then .Clear() and .Remove() don't?
Clear and Remove only remove them locally. DeleteOnSubmit() sets it to be deleted in the context so it will actually be removed from the database.
Stephan
I guess I was thrown by the method name, expecting Delete*OnSubmit* to delete the records *OnSubmit*. Thanks for the answer though :)