приведите к оператору возврата в использовании () {}, блок Располагает перед выполнением

Скорее всего, это сделано с помощью перезаписи URL ...

Веб-сервер принимает URL-адреса, аналогичные адресам в адресной строке вашего браузера & amp; переназначение их на страницы ASPX за кулисами

Это можно сделать в модуле HTTP .NET или в качестве обработчика ISAPI в IIS

На своем сайте Скотт Гатери имеет хорошую статью о перезаписи URL

http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx

49
задан Neil Fenwick 8 October 2009 в 06:14
поделиться

2 ответа

Когда вы вызываете GetAllAnimals , он фактически не выполняет никакого кода до тех пор, пока вы не перечислите возвращенный IEnumerable в цикле foreach.

DataContext удаляется, как только возвращается метод оболочки, прежде чем вы перечислить IEnumerable.

Простейшим решением было бы сделать метод оболочки также итератором, например:

public static IEnumerable<Animal> GetAllAnimals() {
    using (AnimalDataContext dataContext = new AnimalDataContext()) {
        foreach (var animalName in dataContext.GetAllAnimals()) {
            yield return GetAnimal(animalName);
        }
    }
}

Таким образом, оператор using будет скомпилирован во внешнем итераторе и будет удален только тогда, когда удален внешний итератор.

Другим решением было бы перечислить IEnumerable в оболочке. Самый простой способ сделать это - вернуть List , например:

public static IEnumerable<Animal> GetAllAnimals() {
    using (AnimalDataContext dataContext = new AnimalDataContext()) {
        return new List<Animal>(dataContext.GetAllAnimals());
    }
}

Обратите внимание, что при этом теряется преимущество отложенного выполнения, поэтому будут получены все животные, даже если вы не они мне не нужны.

57
ответ дан 7 November 2019 в 11:50
поделиться

Причина в том, что метод GetAllAnimals не возвращает коллекцию животных. Он возвращает перечислитель, способный возвращать животное за раз.

Когда вы возвращаете результат вызова GetAllAnimals внутри блока using, вы просто возвращаете перечислитель. Блок using удаляет контекст данных перед выходом из метода, и в этот момент перечислитель еще не прочитал никаких животных. Когда вы затем пытаетесь использовать счетчик, он не может получить никаких животных из контекста данных.

Обходной путь - заставить метод GetAllAnimals также создать счетчик. Таким образом, блок using не будет закрыт, пока вы не перестанете использовать этот перечислитель:

public static IEnumerable<Animal> GetAllAnimals() {
   using(AnimalDataContext dataContext = new AnimalDataContext()) {
      foreach (Animal animal in dataContext.GetAllAnimals()) {
         yield return animal;
      }
   }
}
11
ответ дан 7 November 2019 в 11:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: