#c_sharp #entity_framework #linq
Сведения об исключении: System.InvalidOperationException: Существует назначенный этой команде Command открытый DataReader, который требуется предварительно закрыть. Ошибка источника: namespace Library.Controls { public partial class CategoryList : System.Web.UI.UserControl { protected void Page_Load(object sender, EventArgs e) { } protected IEnumerableGetCategories() { return new Repository().namebook .Select(p => p.genre_book.NAME_GENRE) .Distinct() .OrderBy(x => x); } protected string CreateHomeLinkHtml() { string path = RouteTable.Routes.GetVirtualPath(null, null).VirtualPath; return string.Format("Главная", path); } protected string CreateLinkHtml(string category) { string selectedCategory = (string)Page.RouteData.Values["category"] ?? Request.QueryString["category"]; string path = RouteTable.Routes.GetVirtualPath(null, null, new RouteValueDictionary() { { "category", category }, {"page", "1"} }).VirtualPath; return string.Format("{1}", path, category); } } } а вот так выглядит repository public class Repository { private EFDbContext context = new EFDbContext(); public IEnumerable namebook { get { return context.namebook; } } code-behind формы где я пытаюсь фильтровать книги public IEnumerable Getbook() { return repository.namebook .OrderBy(b => b.ID_BOOK) .Skip((CurrentPage - 1) * pageSize) .Take(pageSize); } private IEnumerable FilterBook() { IEnumerable namebook = repository.namebook; string currentCategory = (string)RouteData.Values["category"] ?? Request.QueryString["category"]; return currentCategory == null ? namebook: namebook.Where(p => p.genre_book.NAME_GENRE == currentCategory); }
Ответы
Ответ 1
Когда вы перебираете элементы в последовательности без предварительной материализации (.ToList()) - то все это время висит открытый DataReader с результатами запроса к БД. В тот момент, когда EF пытается сделать ленивую загрузку - делается еще один запрос к БД. Тут-то и срабатывает ограничение - в каждом соединении с БД может быть только один активный запрос. Если вы используете MS SQL Server, то можно дописать к строке подключения параметр MultipleActiveResultSets=True - это снимет ограничение. Для других СУБД такой ситуации нужно избегать. Например, через предварительную материализацию запросов (т.е. расстановку этих .ToList()).Ответ 2
Необходимо материализовать ваш запрос в любую коллекцию return new Repository().namebook // для Distinct придется реализовать IEquatable.Distinct() .OrderBy(p => p.genre_book.NAME_GENRE) .Select(p => p.genre_book.NAME_GENRE) .ToArray(); Пока вы не материализовали коллекцию, ваш запрос не выполнен и соответственно ридер не закрыт Ответ 3
На мой взгляд, проблема в том, что Вы пытаетесь быстро выполнить один и тот же запрос дважды (предыдущий еще не успел отработать). Обычно данная проблема появляется с весьма тяжелыми запросами. Чтобы включить данную возможность надо подправить ConnectionString - добавьте "MultipleActiveResultSets=True". Подробнее здесь и здесь. P.S. Ранняя материализации - это не всегда хорошо.
Комментариев нет:
Отправить комментарий