#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 IEnumerable GetCategories()
{
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. Ранняя материализации - это не всегда хорошо.
Комментариев нет:
Отправить комментарий