2015-03-23 6 views
0

У меня есть структура, как этоОшибка при сохранении связанных объектов в Entity Framework

DRDLines:

ID 
DrawingRevisionID 

DrawingRevision:

ID 
Name 

они связаны в один-ко-многим отношения.

В этом примере кода

DRDLine line; 
 

 
using (var db = new AMPX_DCEntities()) 
 
{     
 
    line = db.DRDLines.Single(p => p.ID == 1); 
 
    System.Console.WriteLine(line.DrawingRevision.ID); 
 
} 
 

 
using (var db = new AMPX_DCEntities()) 
 
{ 
 
    var id = 12; 
 
    line.DrawingRevisionID = id; 
 
} 
 

 
using (var db = new AMPX_DCEntities()) 
 
{ 
 
    db.Entry(line).State = System.Data.Entity.EntityState.Modified; 
 
    db.SaveChanges(); 
 
}

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

реляционного нарушение ограничения целостности произошло: Значение свойства (ов) 'DrawingRevision.ID' на одном конце отношения не соответствуют значениям свойств 'DRDLine.DrawingRevisionID' на другом конце.

То, что я нашел: это не обновляет отношения в DRDLines внутри DrawingRevision

отладки я вижу:

line.DrawingRevision.DRDLines[0].ID != line.DrawingRevisionID 

Если удалить линию

System.Console.WriteLine(line.DrawingRevision.ID); 

или написать это так

System.Console.WriteLine(line.DrawingRevisionID); 

все идет без ошибок. Но мне нужна эта линия, которая будет использоваться.

Итак, как я могу это исправить?

БЛАГОДАРЯ

+0

Есть ли 'AMPX_DCEntities' ваш тип' DbContext'? – Richard

+0

Да. Он держится от DBContext –

ответ

0

Я думаю, что проблема вызвана повторно создает новый контекст, а затем утилизации его. При установке DrawingRevisionID здесь

using (var db = new AMPX_DCEntities()) 
{ 
    var id = 12; 
    line.DrawingRevisionID = id; 
} 

линия отсоединяется от DbContext, из которого он был retreived, но не привязан к новому DbContext вы создали, следовательно, EF не будет телеграфировать отношения, когда вы измените идентификатор.

Вы можете прикрепить объект строки обратно в контексте перед изменением ID

db.DRDLines.Attach(line); 

Это изменит как идентификаторы (хотя вы могли бы просто изменить другой идентификатор вручную). Поскольку этот контекст затем удаляется, вам может потребоваться установить EntityState для Modified для DrawingRevision (или, по крайней мере, свойства ID) в последнем сеансе DbContext.

Кроме того, я бы добавил Include к исходному запросу, чтобы с нетерпением загрузить DrawingRevision. В настоящий момент он загружается только при запросе идентификатора на линии System.Console, поэтому почему поведение отличается. Это также вызывает дополнительную поездку в базу данных.Включение его в состав будет более эффективным и более предсказуемым.

+0

Спасибо за ваше время. Но это не помогает. У меня большое приложение. Итак, я получаю данные для редактирования пользователем, чем я их сохраняю. Это разные части программы - загрузка и сохранение. Итак, да, это разные контексты. И у меня такая же ошибка, когда я пытаюсь подключиться. И да, если я сделаю что-то подобное, используя (var db = new AMPX_DCEntities()) { var id = 12; line.DrawingRevision = db.DrawingRevisions.Single (p => p.ID == id); line.DrawingRevisionID = id; } Он отлично работает ... –

+0

Но у меня есть много объектов, связанных с DRDLines. Так было бы так больно делать эти изменения для каждого из них .... –

+0

@ АннаСмородинова Нет серебряной пули. Вам необходимо либо перезагрузить, либо связать объекты, с которыми вам нужно работать, с текущим 'DbContext'. (Ретро-фитинг - большая задача, но это то, что происходит, когда вы обнаруживаете, что у вас системный дефект в базе кода.) – Richard

Смежные вопросы