Entity Framework: с этой командой уже существует открытый DataReader, который должен быть закрыт первым - PullRequest
8 голосов
/ 28 октября 2011

Этот вопрос относится к этому :

Мой метод хранилища имеет следующий код:

 public IEnumerable<ApplicationPositionHistory> GetApplicationPositionHistories(int applicantId, int positionId)
        {
            return context.ApplicationsPositionHistory.Where(d => d.applicantPosition.ApplicantID == applicantId && d.applicantPosition.PositionID == positionId).Include(o => o.applicantPosition) ;
        }

Мой HTML имеет этот код:

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.applicantPosition.Applicant.name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.applicantPosition.Position.name)
        </td>

Полное исключение:

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

Было добавлено в первой строке HTML @ Html.DisplayFor (modelItem => item.applicantPosition.Applicant.name)

Ответы [ 5 ]

22 голосов
/ 28 октября 2011

Быстрое решение:

public IEnumerable<ApplicationPositionHistory> GetApplicationPositionHistories(int applicantId, int positionId)
    {
        return context.ApplicationsPositionHistory.Where(d => d.applicantPosition.ApplicantID == applicantId && d.applicantPosition.PositionID == positionId).Include(o => o.applicantPosition).ToList() ;
    }

Если вы хотите узнать, почему это решает вашу проблему, прочтите о том, как работает LINQ и отложенное выполнение .В двух словах - если вы не «принудительно» выполняете выборку путем «перечисления» запроса ToList, он фактически выполняется слишком поздно - в поле зрения.И это вызывает проблемы с другими запросами, которые хотят использовать то же соединение.

12 голосов
/ 18 декабря 2012

Вы пытались добавить MultipleActiveResultSets=true; в строку подключения?

6 голосов
/ 20 июля 2012

Эта ошибка возникает, когда новый запрос будет выполнен, пока вы находитесь внутри другого запроса. Предположим, у вас есть что-то вроде этого

@Html.DisplayFor(modelItem => item.Device.Name)

и в вашей модели устройства у вас есть

    public string Name
    {
        get
        {
            return String.Format("{0} {1}", Brand.BrandName, Model.ModelName);
        }
    }

тогда, поскольку для оценки Device.Name требуется запросить его бренд и модель, он станет запросом внутри запроса, поэтому решение состоит в том, чтобы включить MutlipleActiveResultSets в строке подключения к базе данных следующим образом:

    <add name="MyDBContext" connectionString="Data Source=.;Initial Catalog=mydb;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
1 голос
/ 28 октября 2011

Обычно не используют объект EF в представлении, но создают объект POCO для модели представления и сопоставляют результат запроса с моделью представления. EF не выполняет запрос в вашем методе репозитория, потому что запрос не выполняется во время определения, а только при попытке доступа к данным. По вашему мнению, вы используете один и тот же запрос много раз, и это не правильно.

Если вы хотите получить доступ к списку объектов, возвращаемых вашим методом репозитория, используйте toList

0 голосов
/ 30 октября 2011

Реальная проблема, если вы ленивы Загружаете ссылку Position из сущности ApplicantPosition до того, как запрос завершит это выполнение. Если вы хотите сохранить отложенное выполнение в этом сценарии, вы можете загрузить ссылку Position на ваш запрос следующим образом:

Включить (o => o.applicantPosition.Select (a => a.Position));

и в ваших GetApplicationPositionHistories продолжает возвращаться IEnumerable.

Другое решение состоит в том, чтобы фактически выполнить запрос в методе GetApplicationPositionHistories, вызвав методы ToList () или ToArrray () для запроса.

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