Как обновить первичный ключ сущности

#vb.net #entity-framework-core

Вопрос:

Прежде чем вы скажете мне, что менять первичный ключ сущности-плохая идея, позвольте мне сказать вам, что я полностью согласен…

Если у меня есть сущность и я попытаюсь изменить первичный ключ, то ДА, это плохая идея для целостности данных.

Однако предположим, что у вас есть сущность, которая используется для объединения двух сущностей. Обе сущности имеют идентификатор (первичный ключ). Сущность, которую вы хотите изменить, ссылается на первичный ключ двух других. Я хочу изменить ссылку на одну из сущностей (но она определена как первичный ключ).

Пример:

 Class Customer
    Public Property Id As Integer
    Public Property Name as String
End Class

Class Address
    Public Property ID As Integer
    Public Property Description As String
End Class

Class CustomerAddressAssignments
    Public Property CustomerID As Integer
    Public Property Customer As Customer
    Public Property AddressID As Integer
    Public Property Address As Address
End Class
 

Конфигурация для заказчика:
builder.ToTable("Customers").HasKey(Function(k) k.ID)
Конфигурация для адреса:
builder.ToTable("Addresses").HasKey(Function(k) k.ID)
Конфигурация для назначений пользовательских адресов:
builder.ToTable("CustomerAddresses").HasKey(Function(k) New With {k.CustomerID, k.AddressID})

Теперь я загрузил назначение CustomerAddress и хочу изменить клиента/адрес, связанный с этим назначением.
Как я должен это сделать? Когда я пытаюсь сохранить изменения, я получаю: Свойство ‘ CustomerAddressAssignment.Адрес’ является частью ключа и поэтому не может быть изменен или помечен как измененный.

Комментарии:

1. Не меняйте первичный ключ. Все так просто. Если вам нужна другая комбинация клиента и адреса, удалите текущую запись и создайте новую с нужной комбинацией. Если вы хотите иметь возможность редактировать существующую запись, добавьте другое свойство в качестве первичного ключа и вместо этого поместите уникальный индекс в комбинацию CustomerID AddressID и. Затем вы можете изменить эти идентификаторы без изменения первичного ключа.

2. Тем не менее, похоже, что изменение CustomerID было бы неправильным в любом случае. Также кажется, что несколько Customers для одного и того же Address тоже было бы неправильно, поэтому эта схема просто кажется неправильной. Я бы предположил , что an Address должен быть уникальным для a Customer , даже если две Address записи содержат одни и те же данные.

Ответ №1:

Вы не меняете первичный ключ; вы меняете внешний ключ? Ваш человек «переезжает», если вы меняете адрес, с которым сопоставлен идентификатор человека в таблице посредников?

Просто удалите старое сопоставление и создайте новое. Или, что еще лучше, установите MovedOutOnDate для свойства значение DateTime.Теперь и создайте новое сопоставление, и таким образом вы сохраните всю историю адресов этого человека для будущих нужд (а текущий адрес(адреса) этого человека определяется как тот(ие), где дата перемещения равна нулю

Если ваша таблица сопоставления начинает хранить больше информации или относится к другим таблицам сама по себе (например, таблица истории заказов, в которой записано, какому лицу и по какому адресу был отправлен/выставлен счет), тогда таблица может иметь свой собственный один столбец PK, так что другие таблицы, к которым она относится, не имеют двух столбцов FK