Инициализация новых объектов вызывает исключение FKC#

Место общения программистов C#
Ответить
Гость
 Инициализация новых объектов вызывает исключение FK

Сообщение Гость »


У меня есть интеграционный тест, демонстрирующий странное поведение, и я думаю, это потому, что я что-то не понимаю в EF Core.

Приведенный ниже код — это всего лишь часть теста «Упорядочить», но он вызывает у меня проблемы. Он должен сделать следующее:
[*]Настройте Contact «Оператора», который содержит ссылку на существующую запись ContactType в базе данных (по сути, Enum). [*]Настройте Contact «Венора», который содержит ссылку на существующий ContactType в базе данных (по сути, Enum).3. Сохраните изменения, чтобы сохранить их. Неработающий пример
[Факт] общественная пустота StackOverflow_BrokenExample() { // Договариваться var CarrierContactType = Context.ContactTypes.FirstOrDefault(ct => ct.Id == ContactTypeEnum.Carrier); var CarrierContact = новый контакт { Имя = «Контакт оператора связи», Адрес1 = "456 Какая-то улица", Актив = правда, ContactTypes = новый список() { операторContactType, }, }; Context.Contacts.Add(перевозчикContact); varvendorContactType = Context.ContactTypes.FirstOrDefault(ct => ct.Id == ContactTypeEnum.Vendor); варvendorContact = новый контакт() { Имя = «Контактное лицо поставщика тестов», Адрес1 = "Другая улица, 123", Актив = правда, ContactTypes = новый список() { вендорКонтактТип, }, }; Context.Contacts.Add(vendorContact); Контекст.СохранитьИзменения(); } Инструкция MERGE конфликтовала с ограничением FOREIGN KEY «FK_ContactTypeXrefs_Contacts_ContactId». Конфликт произошел в базе данных «VF_BillOfLading», таблица «dbo.Contacts», столбец «Id».

Сгенерированный SQL включает в себя следующее:

dbug: 20.09.2023 12:15:31.172 CoreEventId.ForeignKeyChangeDetected[10803] (Microsoft.EntityFrameworkCore.ChangeTracking) Свойство внешнего ключа «Contact.Id» было обнаружено как измененное с «-2147482647» на «1» для объекта с ключом «{Id: 1}». dbug: 20.09.2023 12:15:31.179 CoreEventId.ForeignKeyChangeDetected[10803] (Microsoft.EntityFrameworkCore.ChangeTracking) Свойство внешнего ключа «Contact.Id» было обнаружено как измененное с «-2147482646» на «2» для объекта с ключом «{Id: 2}». информация: 20.09.2023 12:15:31.227 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) Выполнено DbCommand (44 мс) [Parameters=[@p38='-2147482647', @p39='2', @p40='-2147482646', @p41='3'], CommandType='Text', CommandTimeout='30 '] ВЫКЛЮЧИТЬ IMPLICIT_TRANSACTIONS; УСТАНОВИТЬ NOCOUNT ON; ОБЪЕДИНИТЬ [ContactTypeXrefs] ИСПОЛЬЗОВАНИЕ ( ЗНАЧЕНИЯ (@p38, @p39, 0), (@p40, @p41, 1)) AS i ([ContactId], [ContactTypeId], _Position) ВКЛ 1=0 КОГДА НЕ СОВПАДАЕТСЯ, ТОГДА ВСТАВИТЬ ([ContactId], [ContactTypeId]) ЗНАЧЕНИЯ (i.[ContactId], i.[ContactTypeId]) ВЫХОД INSERTED.[Id], INSERTED.[Создан], i._Position; Рабочий пример [Факт] общественная пустота StackOverflow_WorkingExample() { // Договариваться var CarrierContact = новый контакт { Имя = «Контакт оператора связи», Адрес1 = "456 Какая-то улица", Актив = правда, }; Context.Contacts.Add(перевозчикContact); var CarrierContactType = Context.ContactTypes.FirstOrDefault(ct => ct.Id == ContactTypeEnum.Carrier); CarrierContact.ContactTypes.Add(carrierContactType); варvendorContact = новый контакт() { Имя = «Контактное лицо поставщика тестов», Адрес1 = "Другая улица, 123", Актив = правда, }; Context.Contacts.Add(vendorContact); varvendorContactType = Context.ContactTypes.FirstOrDefault(ct => ct.Id == ContactTypeEnum.Vendor); vendorContact.ContactTypes.Add(vendorContactType); Контекст.СохранитьИзменения(); } Мысли и устранение неполадок [*]Похоже, что EF не может соединить записи ContactType и Contact при инициализации в одном и том же объекте. SQL предполагает, что он пытается вставить запись ContactTypeXref с -21474822647 и -21474822646 в качестве поля Contact.Id (значения по умолчанию), хотя в журнале указано, что идентификаторы были просто установлено значение 1 и 2 соответственно.
[*]
Когда объекты Contact инициализируются с пустыми свойствами ContactType, а затем изменяются позже, я подозреваю, что трекер EF может отслеживать, а затем вставлять внешнюю ссылку записывает соответственно.
[*]
Ниже приведен класс ContactTypeConfiguration. Возможно, здесь отсутствует поле, специально обозначенное как ключ?

public void Configure (Builder EntityTypeBuilder) { builder.ToTable( Имя Таблицы, x => x.HasComment( «Табличное представление ContactTypeEnum для ссылочной целостности. Не редактируйте без соответствующего изменения Enum в коде.»)); builder.Property(x => x.Id) .ValueGeneratedNever(); строитель.HasData( новый список { new() { Id = ContactTypeEnum.Carrier, Name = "Carrier" }, new() { Id = ContactTypeEnum.Customer, Name = "Клиент" }, new() { Id = ContactTypeEnum.Shipper, Name = "Отправитель" }, new() { Id = ContactTypeEnum.Vendor, Name = "Vendor" }, }); } Я что-то упустил или нет способа сразу инициализировать полностью гидратированный объект в EF?
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»