2014-09-02 2 views
3

У меня есть 2 класса (Пользователь и устройство), как определено ниже.EntityFramework Explicit Loading не извлекает все объекты

public class User { 
    public int UserId { get; set; } 
    public virtual ICollection<Device> Devices { get; set; } 
    ... 
} 

public class Device { 
    public int UserId; 
    public virtual User User { get; set; } 
    ... 
} 

У меня есть хранилище для каждого из этих двух сущностей, и я отключил отложенную загрузку в моем контексте данных, например, так.

public class MyDbContext : DbContext 
{ 
    public MyDbContext() 
     : base(name=MyDbContext) 
    { 
     this.Configuration.LazyLoadingEnabled = false; 
    } 
} 

Я пытаюсь получить для всех устройств, связанных с учетной записью пользователя.

Я попытался сделать это двумя разными способами.

Подход # 1 - Вызов нагрузки на пользователя, связанный собственности

using (MyDbContext dbContext = new MyDbContext()) 
{ 
    // performing some database operations ... 

    var user = dbContext.Users.Find(8); 

    // do some operations 

    if (user.Devices == null or user.Devices.Count() ==0) 
    dbContext.Entry(user).Collection(u => u.Devices).Load(); 

    var devices = user.Devices; 
} 

Подход № 2 - Извлечение из множества устройств с помощью которых

using (MyDbContext dbContext = new MyDbContext()) 
{ 
    // performing some database operations ... 

    var user = dbContext.Users.Find(8); 

    // do some operations 

    if (user.Devices == null or user.Devices.Count() ==0)   
    var devices = dbContext.Devices.Where(d => d.UserId == user.UserId).ToList(); 
} 

По какой-то причине, подход # 1 не всегда получить все устройства, однако подход №2 получает все устройства! Может кто-нибудь, пожалуйста, объясните мне, что я делаю неправильно?

Я начал профайлер SQL Server, чтобы узнать, что я делаю что-то неправильно. Запросы, которые генерировались обоими подходами, были идентичны. Поэтому я действительно смущен тем, что я делаю неправильно!

+0

Какая версия Entity Framework? –

+0

Entity Framework 5 –

ответ

4

Может кто-нибудь объяснить мне, что я делаю неправильно?

Я не могу объяснить, почему вы испытываете то, что вы испытываете, но лично я не использую Find() ни Load() как методы сложны с точки зрения того, как они работают с локальным кэшем контекста. Поэтому я бы рекомендовал следующий запрос:

var user = dbContext.Users 
    .Include(u => u.Devices); 
    .FirstOrDefault(u => u.id = 8); 

Поскольку вы извлекаете только одного пользователя там нет Cartesian вопросов. Этот запрос заполнит контекст пользователем и всеми устройствами, связанными с пользователем, в одном заявлении.

Если вы действительно нуждались в отдельную переменную со всеми устройствами впоследствии:

var devices = user.Devices; 

важно замечание о мой ответ, потому что я обычно иметь дело с Entity Framework в веб-среде, мой код постоянно создает/удаляет контекст, поэтому локальный кеш на Entity Framework почти бесполезен. Для не-безгосударственного приложения (Winforms/WPF) это не может быть лучшим решением.

Обновлено За ваш комментарий

Есть ли другой способ загрузки в более позднее время?

Как Brendan Green's Comment упоминалось вы можете использовать:

var devices = dbContext.Devices 
    .Where(w => w.UserId == 8); 

(Пожалуйста, знайте, что это не выполняется запрос к источнику данных).

+0

Я новичок в инфраструктуре Entity, поэтому я до сих пор не полностью знаком с различными выражениями. Включает ли получение всех устройств с идентификатором пользователя 8? Или он извлекает все устройства из базы данных и затем фильтрует те, чей идентификатор пользователя равен 8? –

+0

первое предложение верно. Чтобы убедить себя, используйте [linqpad] (http://www.linqpad.net/) – tschmit007

+0

@ParthShah Я также обновил свой ответ, чтобы уточнить этот вопрос. –

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