Обновление многоуровневых свойств в Entity Framework - PullRequest
0 голосов
/ 06 марта 2020

У меня есть структура сущностей с несколькими уровнями свойств, каждая запись таблицы заголовков имеет несколько записей дочерней таблицы, и отношение проходит через несколько уровней. Диаграмма таблицы показана здесь:

enter image description here

Мне нужно получить все данные, относящиеся к одной записи в таблице ECNEntries, для отображения в сетке. Пользователь может редактировать записи, удалять некоторые, добавлять больше записей на всех уровнях.

Я могу получить все данные для конкретной записи, например:

var ECNEntryInDb = ECNEntriesRepo.FindAll(f => f.ECNStages
                                .Select(i => i.ECNComponentDetails
                                    .Select(j => j.ECNMaterialReferenceDetails
                                        .Select(k => k.ECNComponentDetails))))
                                        .Where(x => x.Id == ECNEntriesData.Id).FirstOrDefault();

Но я не могу найти способ обновить эти данные обратно в базу данных.

Когда я попробовал вот так:

var xx = Mapper.Map<DAL.Entities.ECNEntries>(ECNEntriesData);
ECNEntriesRepo.Update(xx);

Я получаю исключение:

Не удалось присоединить сущность типа «ProductionControl.DAL.Entities.ECNEntries», потому что другая сущность того же типа уже имеет то же значение первичного ключа. Это может произойти при использовании метода «Присоединить» или установке состояния объекта на «Неизменен» или «Изменен», если какие-либо объекты в графе имеют конфликтующие значения ключей. Это может быть потому, что некоторые объекты являются новыми и еще не получили сгенерированные базой данных значения ключей. В этом случае используйте метод «Добавить» или состояние добавленной сущности для отслеживания графика, а затем установите для состояния не новых сущностей значение «Неизмененные» или «Измененные», в зависимости от ситуации.

И когда я попробовал это:

var ECNEntryInDb = ECNEntriesRepo.FindAll(f => f.ECNStages
                                    .Select(i => i.ECNComponentDetails
                                        .Select(j => j.ECNMaterialReferenceDetails
                                            .Select(k => k.ECNComponentDetails)))).Where(x => x.Id == ECNEntriesData.Id).FirstOrDefault();
                                //var ECNEntryInDb = ECNEntriesRepo.FindById(ECNEntriesData.Id);

Mapper.Map<BL.DTO.ECN.ECNEntries, DAL.Entities.ECNEntries>(ECNEntriesData, ECNEntryInDb);
ECNEntriesRepo.Update(ECNEntryInDb);

Вот что я получаю:

Операция завершилась неудачей: Невозможно изменить отношение, поскольку одно или несколько свойств внешнего ключа не обнуляется. Когда в отношение вносится изменение, для соответствующего свойства внешнего ключа устанавливается нулевое значение. Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, свойству внешнего ключа должно быть назначено другое ненулевое значение или несвязанный объект должен быть удален.

I попробовал некоторые решения, предложенные на этой странице , такие как добавление составных ключей и все. Это тоже не сработало. Выдает исключение, например:

Добавление отношения с сущностью, находящейся в состоянии «Удалено», недопустимо

Это пример структуры данных:

"EcnEntries": [
                {
                    "Id": 49,
                    "ECNHeaderId": 11,
                    "ECNVersionId": 8,
                    "ECNVersion": null,
                    "ECNPartNumber": "280384-01/01M",
                    "ECNStages": [
                        {
                            "Id": 25,
                            "ECNEntriesId": 49,
                            "OperationNo": "006",
                            "WorkCenterId": 198,
                            "ChangesRequired": "asxa",
                            "ReasonForChanges": "erte",
                            "ECNComponentDetails": [
                                {
                                    "Id": 31,
                                    "ECNStagesId": 25,
                                    "CurrentBOMPartNumber": "jhjhk",
                                    "ReplacementComponentPartnumber": "uyuyuy",
                                    "ECNMaterialReferenceDetails": [
                                        {
                                            "Id": 38,
                                            "ECNComponentDetailsId": 31,
                                            "MaterialReferenceNumber": "323"
                                        },
                                        {
                                            "Id": 39,
                                            "ECNComponentDetailsId": 31,
                                            "MaterialReferenceNumber": "12"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]

РЕДАКТИРОВАТЬ

Это то, что делает функция обновления в реализации репозитория. Как я могу также изменить статус ссылающихся объектов дочерней таблицы?

public void Update(T entity)
        {
            contextFactory.GetDataContext().Entry(entity).State = EntityState.Modified;
        }

Кто-нибудь может предложить способ обновить эти данные? Нужно ли перебирать каждого ребенка и обновлять данные? В этом случае я также запутался, как перебирать данные, поступающие из пользовательского интерфейса и объекта из базы данных одновременно, чтобы применить изменения. Я не уверен, что я испортил что-то действительно простое.

Заранее спасибо.

1 Ответ

0 голосов
/ 09 марта 2020

Как сказал @jdweng, проблема была в Automapper. Эта ссылка оказалась полезной.

Автоматизатор заменял ссылающиеся объекты дочерней таблицы, что в конечном итоге установило для ссылки значение null. это вызывало ошибку.

...