2016-07-05 4 views
0

Рассмотрим следующие (очень упрощенно) объектов:Entity Framework ленивая загрузка неправильная организация

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class Answer 
{ 
    public int Id { get;set; } 
    public virtual User User { get; set; } 
    public string Text { get;set } 
} 

public class TeamMember 
{ 
    public int Id { get;set; } 
    public virtual User User { get; set; } 
    public string Role { get; set; } 
} 

В моем картографа я могу установить штраф пользователя, но как только выполняется следующий код (до каких-либо изменений сохраняется в БД)

if (teamMembers.Select(x => x.User).Contains(currentUser))

где teamMembers является список teamMembers и CurrentUser является объект пользователя загружается из дб, то свойство User ответа устанавливается предыдущее значение из базы данных. Мое понимание заключается в том, что, поскольку я еще не получил доступ к свойству User для ответа до того, как он еще не загружен из базы данных, и это то, что происходит (он был ленивый загружен?).

Я мог бы исправить это, прочитав Пользователь, даже не установив его в mapper, но то, что я не могу понять, - это почему, когда я обращаюсь к свойству User TeamMember, загружается и устанавливается свойство User Answer? Является ли это ожидаемым поведением, поскольку оба объекта связаны с одним и тем же пользователем (т. Е. В базе данных они имеют один и тот же User_Id как внешний ключ), а при загрузке для TeamMembers EF пытается быть умным и заполнять другие объекты, которые ссылаются на него, еще не загружены?

ответ

0

Объекты не сохраняются/кэшируются элементами, которые имеют ссылки на них, но хранятся вместе со своими соответствующими коллекциями.

Как только вы загрузили этого пользователя через ссылку teamMembers, он был загружен ... период. Когда вы перешли к ссылке с другого элемента/объекта, было бы глупо, если бы он пошел и снова загрузил его, когда он уже имеет этот объект в памяти.

Это все по дизайну, и это имеет смысл ... если, например, вы хотели сохранить все эти объекты одновременно, он сначала создавал бы пользователя, получал бы личность/ключ для него, а затем сохранял бы другие объекты, которые ссылаются на этот ключ, который был сгенерирован.

исх: https://msdn.microsoft.com/en-us/data/hh949853.aspx#3

»... ObjectContext будет проверить, если объект с тем же ключом уже уже был загружен в его ObjectStateManager Если предприятие с же ключами уже присутствует EF будет. включите его в результаты запроса . Хотя EF все еще выдаст запрос к базе данных, это поведение может обойти большую часть стоимости материализации объекта несколько раз ».

+0

Спасибо за ваш ответ, но он не полностью отвечает на мой вопрос (возможно, недостаточно ясен). Предположим, что у меня есть два пользователя: 'User1 {}' и 'User2 {}'. Может ли кто-нибудь объяснить, почему это так, когда я устанавливаю значение 'answer.User' с' User1 {} 'на' User2 {} ', а затем без сохранения запускает select (например,' teamMembers.Select (x => x .User) .Contains (currentUser) ') в моей коллекции teamMembers, а затем возвращает свойство пользователя моего ответа обратно в' User1 {} '? – msokrates

+0

Был ли пользователь2 уже сохранен в базе данных или он только «в памяти» в этот момент? –

+0

Я установил answer.User для User2 (который я извлекаю из базы данных), но не сохраняю это изменение, если это то, что вы имеете в виду. – msokrates

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