Search code examples
mysqlasp.net-mvcerror-handlingdatareader

How can I select special Index of model in View?


I use this query in controller for creating a list from join four tables:

var ViewModel = (from APP in db1.application
                 where APP.APP_STATUS == "TO_DO"
                 join APPDEL in db1.app_delegation on APP.APP_UID equals APPDEL.APP_UID
                 join Con in db1.content on APPDEL.TAS_UID equals Con.CON_ID
                 join BPMNPRC in db1.bpmn_process on APPDEL.PRO_UID equals BPMNPRC.PRJ_UID
                 join RUSRE in db1.rbac_users on APP.APP_INIT_USER equals RUSRE.USR_UID
                 where APPDEL.TAS_UID == Con.CON_ID 
                    && Con.CON_CATEGORY == ("TAS_TITLE")
                    && APP.APP_UID == APPDEL.APP_UID 
                    && APPDEL.DEL_THREAD_STATUS == "OPEN" 
                    && APPDEL.USR_UID == bpmUseid.BPMSID
                 select new ApplicationContentViewModel
                         {
                             creator = RUSRE,
                             app_delegation = APPDEL,
                             application = APP,
                             content = Con,
                             task = BPMNPRC,
                         }).AsEnumerable();
return View(ViewModel);

But I need to select a special record in APPDEL (app_delegation), then retrieve name of this record.

I use this command in view for selecting item by field of DEL_INDEX:

@foreach (var item in Model)
{
  <th>                                                    
  @(item.app_delegation.DEL_INDEX == Model.Max(x => x.app_delegation.DEL_INDEX) - 1 ? item.creator.USR_LASTNAME : "");
 </th>  
}

In fact, I want to select the max value of DEL_INDEX - 1, and retrieve its last name.

Unfortunately, I get this error:

System.Data.Entity.Core.EntityCommandExecutionException:: 'An error occurred while executing the command definition. See the inner exception for details.'

Inner Exception:

MySqlException: There is already an open DataReader associated with this Connection which must be closed first

How can I handle this error?


Solution

  • I think you should use ToList() method instead of AsEnumerable() before executing expression Model.Max(x => x.app_delegation.DEL_INDEX) as shown below:

    var ViewModel = (from APP in db1.application
                     where APP.APP_STATUS == "TO_DO"
                     join APPDEL in db1.app_delegation on APP.APP_UID equals APPDEL.APP_UID
                     join Con in db1.content on APPDEL.TAS_UID equals Con.CON_ID
                     join BPMNPRC in db1.bpmn_process on APPDEL.PRO_UID equals BPMNPRC.PRJ_UID
                     join RUSRE in db1.rbac_users on APP.APP_INIT_USER equals RUSRE.USR_UID
                     where APPDEL.TAS_UID == Con.CON_ID 
                     && Con.CON_CATEGORY == ("TAS_TITLE")
                     && APP.APP_UID == APPDEL.APP_UID 
                     && APPDEL.DEL_THREAD_STATUS == "OPEN" 
                     && APPDEL.USR_UID == bpmUseid.BPMSID
                     select new ApplicationContentViewModel
                     {
                         creator = RUSRE,
                         app_delegation = APPDEL,
                         application = APP,
                         content = Con,
                         task = BPMNPRC,
                     }).ToList(); // here is the change
    

    Explanation

    By calling AsEnumerable() the data reader is kept open and when executing Model.Max() as LINQ to Objects throws exception due to MySQL Connector you're using doesn't have support for MARS (Multiple Active Result Sets) yet. Using ToList() methods ensures the data reader operation is completed when lazy loading checks all navigation properties.

    Side note:

    Assumed you're using EF, try eager loading with Include() to add related objects in single statement when dealing with multiple queries.

    Similar issue:

    Mysql Linq There is already an open DataReader associated with this Connection which must be closed first