2016-03-04 4 views
1

У меня есть метод, который дает мне список объектов, например.Сфера применения оператора

public IEnumerable<Person> GetPerson() 
{ 
    using (myEntities ctx = new myEntities()) 
    { 
     return ctx.Person.Where(x => x.Age < 50); 
    } 
} 

где-то еще я использую этот метод

public void Main() 
{ 
    var pList = GetPerson(); 
    pList = pList.Where(x => x.Age < 40); 

    Person Item = pList.FirstOrDefault(); //materialization here 
} 

Когда я называю FirstOrDefault() избранных в настоящее время genereated и данные загружаются из базы данных.

Вопрос: является ли объем using (myEntities ctx = new myEntities()) достижением материализации?

С одной стороны, это связано с тем, что оно управляет выбором/соединением с базой данных и которое создается при материализации - с другой стороны, оно вызывается вне метода и может быть где угодно в коде - вне использования директивы

+4

Я редактировал название вашего вопроса, так как это, используя * о *, не используя * директивы *. –

+0

Вы пытались выполнить этот код, он работает? –

ответ

7

Нет, заявление using не исчерпало все возможности материализации запроса.

Если, вызывающий Person, уже возвращает полностью материализованную коллекцию, что маловероятно и не является типичным.

Что происходит следующее:

  1. Конструируется контекст
  2. Вы называете Person свойство контекста, и складка на запросе LINQ

    Вероятно, это будет возвращать отложенный запрос , который еще не исполнен

  3. Вы удаляете контекст
  4. Вы возвращаете LINQ запрос вы построили
  5. Вы называете FirstOrDefault на запрос, пытаясь выполнить его

На данный момент вероятным результатом является то, что происходит сбой кода, потому что вы пытаетесь выполнить запрос с использованием контекста, который был расположены.

+0

ОК спасибо за подробное объяснение – Byyo

1

Вот как сделать, используя работу:

void Main() 
{ 
    Person Item = UsingPerson(ps => ps.Where(x => x.Age < 40).Take(1)).FirstOrDefault(); 
} 


public T[] UsingPerson<T>(Func<IQueryable<Person>, IQueryable<T>> project) 
{ 
    using (myEntities ctx = new myEntities()) 
    { 
     return project(ctx.Person.Where(x => x.Age < 50)).ToArray(); 
    } 
}