Вы не опубликовали код для вашего метода InsertOrUpdate, но я подозреваю, что именно в этом проблема. Могу поспорить, что в этом методе в какой-то момент вы делаете что-то эквивалентное:
context.Machines.Add(machine);
Когда вы вызываете DbSet.Add (или изменяете состояние объекта на Добавленный), вы фактически добавляете весь граф в контекст. Этот процесс остановится, когда встретится с объектом, который отслеживается контекстом. Таким образом, если у вас есть машинный объект, который ссылается на пользовательский объект, и ни один из этих объектов не отслеживается контекстом, то и машинный объект, и пользовательский объект будут добавлены в контекст и окажутся в состоянии «Добавлен». EF затем вставит их обе как новые строки в базу данных.
Что вам нужно сделать, о чем говорилось в другом ответе, это убедиться, что EF знает, что существующий объект пользователя существует в базе данных, убедившись, что его состояние не изменилось (или, возможно, не изменено) и не добавлено, когда Вы экономите.
Существуют различные способы сделать это, и трудно понять, какой из них лучше для вас, не видя больше того, как работают ваше приложение и репозиторий. Один из способов - убедиться, что контекст, используемый для запроса пользователя, совпадает с контекстом, используемым для сохранения. Таким образом, EF уже будет отслеживать существующий объект пользователя и не будет добавлять его при вызове Add.
Другой способ - сообщить вашему хранилищу как-то, является ли пользовательский объект новым. Часто люди используют первичный ключ, чтобы определить это - нулевой ключ указывает на новый объект, ненулевой указывает на существующий объект. Вы также можете передать флаг в свой репозиторий.
Затем вы можете вызвать Add, чтобы добавить график, но затем установить состояние объекта User в значение «Без изменений» (или «Изменено», если оно могло быть изменено с момента запроса), если это существующий пользователь. Это не позволит EF вставить нового пользователя в базу данных.