#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
тоже было бы неправильно, поэтому эта схема просто кажется неправильной. Я бы предположил , что anAddress
должен быть уникальным для aCustomer
, даже если двеAddress
записи содержат одни и те же данные.
Ответ №1:
Вы не меняете первичный ключ; вы меняете внешний ключ? Ваш человек «переезжает», если вы меняете адрес, с которым сопоставлен идентификатор человека в таблице посредников?
Просто удалите старое сопоставление и создайте новое. Или, что еще лучше, установите MovedOutOnDate
для свойства значение DateTime.Теперь и создайте новое сопоставление, и таким образом вы сохраните всю историю адресов этого человека для будущих нужд (а текущий адрес(адреса) этого человека определяется как тот(ие), где дата перемещения равна нулю
Если ваша таблица сопоставления начинает хранить больше информации или относится к другим таблицам сама по себе (например, таблица истории заказов, в которой записано, какому лицу и по какому адресу был отправлен/выставлен счет), тогда таблица может иметь свой собственный один столбец PK, так что другие таблицы, к которым она относится, не имеют двух столбцов FK