2015-01-22 5 views
4

У меня есть очень простая операция EF, которая не: разорвать отношения между двумя субъектами, как показано в коде ниже:отношений не установлен в нуль

public async Task RemoveCurrentTeacherOfGroup(int groupId) 
{ 
    var group = await _dataContext.Groups.SingleAsync(g => g.Id == groupId); 
    group.Teacher = null; 
    await _dataContext.SaveChangesAsync(); 
} 

База данных генерируется код-первых. Объекты определяются следующим образом:

public class Teacher 
{ 
    public int Id { get; set; } 
    .. 
    public virtual List<Group> Groups { get; set; } 
} 
public class Group 
{ 
    public int Id { get; set; } 
    .. 
    public virtual Teacher Teacher { get; set; } 
} 

Однако, нарушая связи не работает, Учитель продолжает указывать на тот же объект. При переходе с отладчиком я вижу, что свойство Teacher не становится null после .Teacher = null. Я попробовал его с синхронной альтернативой, которая имела такой же эффект:

public void RemoveCurrentTeacherOfGroup(int groupId) 
{ 
    var group = _dataContext.Groups.Single(g => g.Id == groupId); 
    group.Teacher = null; 
    _dataContext.SaveChanges(); 
} 

ответ

5

Если Teacher не загружен, вы не можете разорвать отношения. Либо включить его (нетерпеливые нагрузки) по запросу:

_dataContext.Groups.Include(g => g.Teacher).Single(g => g.Id == groupId); 

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

var teacher = group.Teacher; 
group.Teacher = null; 

Вы видите, что "Teacher является не null после установки его на null ", потому что отладчик получает доступ к свойству для чтения (lazy-load it) после того, как вы установили его в null.

значение уже null, прежде чем попасть в group.Teacher = null линию, так как вы ранее не загрузили его (вы не можете, однако отлаживать это, так как доступ к свойству для чтения приведет к EF на самом деле загрузить его, если ленивая загрузка включена). Если вы видите значение свойства с отладчиком до, установив его в null, оно будет работать как ожидалось и нарушит связь, поскольку Teacher будет загружен

+1

Спасибо! Off Topic: Я думаю, что это недостаток в EF. Объект прокси-сервера может обнаруживать, что в его сеттере установлено значение null; внешний ключ известен (используется для ленивой загрузки), поэтому EF может удалить его и установить свойство в измененное состояние. – mnwsmit

+0

@mnwsmit Я предполагаю, что это по соображениям производительности: если вы собираетесь просто «установить связанный объект», нет необходимости округлять до базы данных, чтобы увидеть, «было ли оно« null », потому что оно не было загружено, или оно было нулевым, потому что оно был фактически нулевым ». Все, что обращается к базе данных, должно быть тщательно выполнено (и установка связанного объекта не обязательно обязательно нуждается) – Jcl

+0

Однако эта информация уже известна: внутри прокси-объекта хранится внешний ключ. Таким образом, EF уже знает, что отношение является только нулевым из-за ленивой загрузки. – mnwsmit