Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework: There is already an open DataReader associated with this Command which must be closed first

This question is related to this:

My repository method has this code:

 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) ;
        }

My Html has this code:

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

The full exception is:

There is already an open DataReader associated with this Command which must be closed first.

It was throw in the first line of the HTML @Html.DisplayFor(modelItem => item.applicantPosition.Applicant.name)

like image 217
Luis Valencia Avatar asked Oct 28 '11 10:10

Luis Valencia


4 Answers

Quick solution :

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() ;
    }

If you want to know, why this fixing your problem, read about how LINQ and deffered execution works. In few words - if you dont "force" execution of the select by "enumerating" query by ToList, it is in fact executed too late - in view. And this is causing trouble with other queries which want to use same connection.

like image 79
rouen Avatar answered Oct 27 '22 06:10

rouen


Generally do not use EF object in view, but create a POCO object for the view model and map the query result on the view model. EF do not execute the query in your repository method because the query are not executed at definition time but only when you try to access the data. In your view you are using the same query many time and this is not correct.

If you want to access the list of object returned by your repository method, use toList

like image 34
Massimo Zerbini Avatar answered Oct 27 '22 04:10

Massimo Zerbini


Have you tried adding MultipleActiveResultSets=true; to your connection string?

like image 12
hofnarwillie Avatar answered Oct 27 '22 06:10

hofnarwillie


This error happens when a new query is going to be executed while you're in inside another query. Consider you have something like this in your view

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

and in your Device model you have

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

then since for evaluating Device.Name it requires to query its Brand and Model it will become query inside query and so the solution is to enable MutlipleActiveResultSets in your database connection string as follows:

    <add name="MyDBContext" connectionString="Data Source=.;Initial Catalog=mydb;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
like image 6
Mohsen Afshin Avatar answered Oct 27 '22 06:10

Mohsen Afshin