Linq2SQL имеет дело со вставками / удалениями в таблице с уникальными ограничениями
У меня есть таблица, которая выглядит следующим образом:
TABLE Foo
{
Guid Id [PK],
int A [FK],
int B [FK],
int C [FK],
}
И уникальное ограничение на A, B и C.
Теперь, скажем, например, вы вставляете строку с новым PK с A = 1, B = 1, C = 1.
SubmitChanges()
, все счастливы.
Теперь вы редактируете таблицу.
Вы удаляете предыдущую запись и вставляете строку с новым номером PK с A = 1, B = 1, C = 1.
SubmitChanges()
БУМ! Уникальное ключевое ограничение SQL-исключения.
Из того, что я вижу, он пытается сначала вставить новую запись, а затем попытаться удалить предыдущую. Я даже могу понять, что невозможно определить порядок, в котором это должно произойти.
Но что я могу поделать? Было бы лучше сделать эти 3 поля составным ПК (и убрать старое), или это не сработает?
На данный момент "решением" является удаление уникальных ограничений из БД (но я не буду этого делать).
2 ответа
Один из вариантов - создать транзакцию (транзакцию, связанную с соединением, или TransactionScope
) - удалить запись и SubmitChanges
, добавьте запись и SubmitChanges
, а затем, наконец, совершить транзакцию (или откат, если вы взорвали).
Обратите внимание, что вы можете связать привязанную к соединению транзакцию через конструктор контекста данных IIRC. TransactionScope
должен также работать, и это легче сделать - но не так эффективно.
В качестве альтернативы, напишите SP, который выполняет эту работу по обмену в базе данных, и получите доступ к этому SP через контекст данных.
У меня такая же проблема. Закончилось написание класса-оболочки с коллекцией сущностей "Добавлено" и "Удалено", которые я поддерживал. А также коллекция "Текущий". Пользовательский интерфейс был привязан к текущей коллекции.
Только когда я иду к сохранению, я вставляю InsertOnSubmit / DeleteOnSubmit, и я анализирую 2 коллекции, чтобы решить, какие сущности делать с чем.