Не удается создать связанный объект в ASP.NET Core с EF Core - PullRequest
1 голос
/ 05 апреля 2019

У меня проблема с созданием связанной сущности в Entity Framework Core 2.0. Я только что создал решение, состоящее из внутреннего проекта Asp.Net Core и проекта UWP, выступающего в роли клиента. Оба решения имеют общую модель. Две модели:

public class UnitOfWork {
    public int UnitOfWorkId { get; set; }
    public string Name { get; set; }
    public Human Human { get; set; }
}

public class Human {
    public int HumanId { get; set; }
    public string Name { get; set; }
    public List<UnitOfWork> WorkDone { get; set; }
}

Как видите, модель очень простая. Один human имеет много units of work. Кстати, бэкэнд подключен к базе данных SQL Azure. Я видел классы миграции, и схема базы данных выглядит хорошо для меня.

Проблема у меня возникает, когда я хочу создать unit of work, ссылающийся на существующий human, используя HTTP. Контроллер довольно прост:

[HttpPost]
public UnitOfWork Post([FromBody] UnitOfWork unitOfWork) {
    using (var db = new DatabaseContext()) {
        db.UnitsOfWork.Add(unitOfWork);
        var count = db.SaveChanges();
        Console.WriteLine("{0} records saved to database", count);
    }
    return unitOfWork;
}

Опять, ничего особенного.

Как я могу создать единицу работы и назначить ее существующему человеку? Если я попробую это с существующим человеком, таким образом

var humans = await Api.GetHumans();
var firstHuman = humans.First();

var unitOfWorkToCreate = new UnitOfWork() {
    Name = TbInput.Text,
    Human = firstHuman,
};

Я получаю эту ошибку:

Невозможно вставить явное значение для столбца идентификаторов в таблице «Люди», если для параметра IDENTITY_INSERT установлено значение OFF

Мне кажется, что установка IDENTITY_INSERT в положение ON решит мою проблему, но я не хочу этого делать. В клиенте я выберу существующий human, запишу имя для unit of work и создам последний. Это правильный путь?

РЕДАКТИРОВАТЬ: После ответа @Ivan Stoev я обновил контроллер UnitOfWork, добавив unitofwork.Human. Это привело к

Newtonsoft.Json.JsonSerializationException: 'Неожиданный конец при десериализации массива. Путь 'human.workDone', строка 1, позиция 86. '

Investigating - видно здесь - EFCore ожидает создания коллекций (например, human.WorkDone) в конструкторе, так что я сделал это, и десериализации больше нет. Тем не менее, теперь у меня есть цикл самообращения:

Newtonsoft.Json.JsonSerializationException: обнаружен самоссылочный цикл с типом 'PlainWorkTracker.Models.UnitOfWork'. Путь «human.workDone».

Есть идеи? Спасибо!

1 Ответ

1 голос
/ 05 апреля 2019

Операция, о которой идет речь, попадает в Сохранение отключенных объектов категория.

Методы

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

Вам нужен способ сообщить EF, что unitOfWork.Human - это существующая сущность. Простейший способ добиться этого - Attach передать его (что пометит его как Unchanged, т. Е. Существует) в контексте перед вызовом Add:

db.Attach(unitOfWork.Human);
db.Add(unitOfWork);
// ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...