#asp.net #linq-to-sql
#asp.net #linq-to-sql
Вопрос:
У меня есть tbl_names со следующими полями:
Id int
Name nvarchar(10)
family nvarchar(20)
Id Name Family
1 John Smith
и предположим, что Id
и name
являются первичным ключом вместе (составной первичный ключ).
и я хочу обновить name
поле в соответствии со значением Id
поля.
DataclassesContext dac=new DataClassesContext();
var query=from record in Dac.tbl_name where record.id=1 select record;
query.name="Raymond";
Dac.Submitchanges();
но я сталкиваюсь со следующей ошибкой:
Value of member 'co_Workshop' of an object of type 'Tbl_Workshop' changed.
A member defining the identity of the object cannot be changed.
Consider adding a new object with new identity and deleting the existing one instead.
Это из-за того, что name
поле является первичным ключом? почему я не могу обновить поле первичного ключа с помощью linq?
Комментарии:
1. Я не могу вспомнить, когда я когда-либо обновлял первичный ключ. Не говорю, что у вас нет причин для этого… У меня просто никогда не было. Интересно, что это вам не позволит. Возможно, это потому, что это единственный идентификатор, который он может связать с базой данных? Таким образом, вам пришлось бы создать его копию с обновленным ключом, добавить его и удалить старый.
2. Зачем вам объединенный идентификатор
{id, name}
? Почему бы просто не сохранитьid
уникальность?3. Я работаю над старой базой данных и не могу изменить ее структуру. да, вы правы, нет причин, но мне это нужно
4. @Micjecito не могли бы вы привести мне пример?
Ответ №1:
Я не уверен, что вы должны найти способ обойти это. Я не могу представить, почему было бы хорошей идеей изменить значение в PK. Вся природа PK заключается в том, что это стабильный идентификатор строки.
В вашем случае вы должны удалить и воссоздать PK, чтобы это было просто поле «Id», а затем, если вам нужно повысить производительность при фильтрации запросов по «имени», просто добавьте индекс в поле «имя». Тот факт, что вы используете только поле «Id» для поиска записи, подтверждает эту идею.
РЕДАКТИРОВАТЬ: я ответил до того, как появились комментарии к вопросу. Теперь, когда я вижу комментарий из OP о «это старая база данных и не могу изменить ее структуру», я бы сказал, что если нет FKS, указывающих на этот PK, то это должно быть довольно простым изменением (удалить и воссоздать PK только с полем «Id», как я упоминал выше). Если на него указывают какие-то FKS, то вариант (хотя и не самый лучший вариант, и он может работать не на всех СУБД) заключается в:
- Удалите FKS
- Удалите PK
- Создайте новый PK только в поле «Id»
- Создайте УНИКАЛЬНЫЙ ИНДЕКС для «Id» и «Name»
- Воссоздайте FK, чтобы указать на УНИКАЛЬНЫЙ ИНДЕКС
Это будет работать на Microsoft SQL Server, и как бы мне не нравилась идея, когда FK указывает на УНИКАЛЬНЫЙ ИНДЕКС, она должна допускать ту же структуру, что и у вас сейчас, плюс LINQ просто увидит единственное поле PK в «Id» и разрешит обновление.
Ответ №2:
По возможности обходным путем является удаление записи, значение первичного ключа которой нуждается в обновлении, и создание новой записи на ее месте.
Ответ №3:
Похоже, что есть способы обойти это, как я упоминал выше. Linq не позволит вам изменить первичный ключ.
Комментарии:
1. Я пробовал, но нет метода Remove ().
DAC.tbl_names.remove()
Ответ №4:
Возникла та же проблема. По устаревшим причинам я не смог удалить столбец, который мне нужно было обновить, из части первичного ключа.
Простым решением было не использовать Linq в этом случае, а использовать T_SQL и выполнить простое обновление.
update tbl_name set name = 'Raymond' where id = 1