Скорее всего, это сделано с помощью перезаписи 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
Когда вы вызываете 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());
}
}
Обратите внимание, что при этом теряется преимущество отложенного выполнения, поэтому будут получены все животные, даже если вы не они мне не нужны.
Причина в том, что метод 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;
}
}
}