C # Entity Framework: с этим подключением уже есть открытый DataReader, который должен быть закрыт первым - PullRequest
7 голосов
/ 26 мая 2011

Я работаю над приложением ASP.NET MVC3 и создал базу данных в MySQL 5.5 , в которой содержится таблица компании, имеющая отношение «один ко многим» с таблицей контактов.

таблица Bedrijf (со свойством навигации " contacts ")

Таблица Контакт

Так как мне пришлось перенять эту базу данных с работающего в данный момент сайта, я сгенерировал модель сущности на основе этой базы данных и написал следующий код для отображения списка компаний (сгруппированных по статусу) с указанием количества контактов в этом компания:

CompanyRepository.cs

...

public IQueryable<Bedrijf> getCompaniesByStatus(int status)
    {
        return entities.Bedrijven.Where(c => c.bedrijf_status == status).OrderBy(c => c.bedrijf_naam);
    }

...

Просмотр вызова 3 частичных просмотра

@{Html.RenderPartial("ucCompaniesByStatus", Model.newCompanies, (new ViewDataDictionary { { "Titel", "Nieuwe bedrijven" } }));}

<br />

@{Html.RenderPartial("ucCompaniesByStatus", Model.activeCompanies, (new ViewDataDictionary { { "Titel", "Actieve bedrijven" } }));}

<br />

@{Html.RenderPartial("ucCompaniesByStatus", Model.inActiveCompanies, (new ViewDataDictionary { { "Titel", "Niet actieve bedrijven" } }));}

Частичное представление

@model IEnumerable<xxx.Models.Bedrijf>

<table id="companytable">
    <tr>
        <th id="thtitle">
            @ViewData["Titel"]
        </th>
        <th id="thactions"></th>
    </tr>

@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.ActionLink(@item.bedrijf_naam, "CompanyDetails", new { id = item.bedrijf_id }) 
            (@item.contacts.Count contact(en))



        </td>
        <td id="actions">
            @Html.ActionLink("Edit", "CompanyEdit", new { id=item.bedrijf_id }) |
            @Html.ActionLink("Details", "CompanyDetails", new { id = item.bedrijf_id }) |
            @Html.ActionLink("Delete", "Delete", new { id = item.bedrijf_id })
        </td>
    </tr>
}
</table>

В моем списке компаний я хотел бы отобразить количество контактов, назначенных этой компании, но я получил следующую ошибку:

Уже существует открытый DataReader, связанный с этим подключением, который должен быть закрыт первым.

Когда захожу в мой файл .edmx и устанавливаю Ленивая загрузка включена: False Я могу получить результат (но счетчик моих контактов не работает (я получаю 0), предполагая, что мои связанные контакты не загружены.):

Как я могу заставить это работать с включенной отложенной загрузкой? Мои навыки новичка в ASP.NET (MVC) на данный момент не позволяют мне найти решение.

Добавление MultipleActiveResultSets = True; в строке подключения web.config часто указывается как решение, но в моем случае разницы нет.

Попробовал .Include в моем CompanyRespository, когда для отложенной загрузки установлено значение False, но я думаю, что сделал это неправильно, так как не знаком с синтаксисом.

Это описание также имеет смысл;

Речь идет не о закрытии соединения. EF правильно управляет подключением. мой понимание этой проблемы заключается в том, что Есть несколько данных поиска команды, выполняемые по одному соединению (или одна команда с несколькими выбирает) в то время как следующий DataReader выполняется до того, как первый закончил чтение. Единственный способ избежать исключения, чтобы разрешить несколько вложенных DataReaders = включить MultipleActiveResultSets. Другая сценарий, когда это всегда происходит, когда вы перебираете результат запрос (IQueryable), и вы будете вызвать отложенную загрузку загруженного объекта внутри итерации.

но не знаю, как мне исправить эту проблему в моем коде с этой информацией. Где / Как использовать @item.contacts.Count, чтобы показать количество контактов?

Заранее спасибо.

Ответы [ 3 ]

15 голосов
/ 27 сентября 2011

У меня была похожая проблема.Заметил, что использует коллекцию IEnumerable и вызывает другую функцию, которая запрашивает базу данных.Поскольку это была коллекция IEnumerable, читатель был открыт.Изменен IEnumerable в список для решения проблемы.

3 голосов
/ 18 апреля 2013

Соединитель MySQL не поддерживает MultipleActiveResultSets, поэтому изменение строки подключения не будет работать.

Чтобы обойти эту проблему, в своем контроллере просто добавьте метод .ToList () туда, где запрашиваются ваши данные. Например ...

public ActionResult Create()
{
    ViewBag.PossibleCompanies = context.Companies.ToList();
    return View();
} 
3 голосов
/ 26 мая 2011

Попробуйте использовать это:

public IQueryable<Bedrijf> getCompaniesByStatus(int status)
{
    return entities.Bedrijven
                   .Include("contacts")
                   .Where(c => c.bedrijf_status == status)
                   .OrderBy(c => c.bedrijf_naam);
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...