Entity Framework ObjectContext может быть в несогласованном состоянии - PullRequest
0 голосов
/ 02 апреля 2019

Я хотел бы понять, почему «ObjectContext может быть в несовместимом состоянии».исключение происходит.Я знаю, что существует множество тем, связанных с похожей проблемой, но ни одна из них не отвечает на мой вопрос.(Ближе всего к моей проблеме: Изменения в базе данных были успешно зафиксированы ... Возможно, ObjectContext находится в несогласованном состоянии )

У меня есть модель Database First, содержащую таблицы:

Training (PK Id)
User (PK Id)
UserTraining(PK (UserId, TrainingId), FK(UserId), FK(TrainingId))
Documentation(PK Id, FK TrainingId)
UserDocumentation (PK (UserId, TrainingId, DocumentationId),
    FK(UserId, TrainingId), FK(DocumentationId))

Все приведенные выше таблицы правильно отображены в коде (все ключи присутствуют и т.ниже:

var type = this.trainingRepository.GetTrainingType(command.Training.TypeId);
var training = new Training(
    type,
    command.Training.Name,
    command.Training.Documentation,
    ...);


if (type.Equals(TrainingType.Mandatory))
{
    var users = this.userRepository.GetAllUsers();
    foreach(var user in users)
    {
        user.AssignTraining(training);//under the hood is created new instance of UserTraining with relation to training and UserDocumentation related to UserTraining and Documentation from training
    }
}

trainingRepository.Add(training);
trainingRepository.SaveChanges();

Есть 2 репозитория, но каждый использует один и тот же экземпляр DBContext (зарегистрированный как PerRequest).

Теперь, если я перемещу добавление и сохранение изменений выше if (type.Equals (TrainingType.Mandatory)) и добавим один ход SaveChanges в конце метода, все пройдет без проблем.

К сожалению, в приведенном выше случае он вызывает исключение, указанное в заголовке.Теперь вопрос - почему добавление в середине, а затем обновление работает, а мое решение - нет?Может ли это быть связано с плохой схемой базы данных или, скорее, с ограничениями EF?

Метод AssignTraining:

public void AssignTraining(Training training)
{
    this.State.UserTrainings.Add(new UserTraining(training));
}

Конструктор UserTraining:

public UserTraining(Training training) : base(new 
DataAccess.Database.UserTraining())
{
    this.State.Training = training;
    if(training.Documentation != null)
    {
        this.State.UserDocumentations.Add(new UserDocumentation(training.Documentation));
    }
}
...