一例发生在cshtml页面中的There is already an open DataReader associated with this Command which must be closed

来源:互联网 发布:vb建立数据库 编辑:程序博客网 时间:2024/06/08 16:01

近日在做MVC页面的时候碰到了发生在cshtml页面的一个错误:

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

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

Source Error: 

Line 184:                foreach (var item in Model)Line 185:                {
Line 186:                    i++;
Line 187:                    <div class="pointbox pointboxnull" id="@item.QuestionsLibrary.IID" data-gid="@item.QuestionsLibraryAndSortGid" data-type="@item.QuestionsLibrary.Type" data-sequence="@item.OptionSequence">@i<span></span></div>Line 188:                }


Source File: e:\TrafficRulesTraining\LMSoft.Web\Views\Member\LastTestPractice.cshtml    Line: 186


当时就有点发蒙,这是什么情况,这个错误不是应该发生在数据库插入或更新语句的时候,有打开的datareader连接吗?这就是一个数据读取一个列表,在cshtml页面中循环读取,怎么会出现这种情况。各种查找,baidu,google没有人遇到我这样得情况。那只能自己找问题所在了。首先因为知道这个问题会发生在公用一个数据连接才会发生。列表读取使用的cs代码如下:

var list = new ExamListService().Get(m => m.ExamMainGID == examMainGid).OrderBy(m => m.IID);

尝试找到这个方法底层,new了一个新的数据库连接。编译执行,问题依旧,看来不是这里的问题。

把目光移到了model的实现。相应的正常的页面,都是自定义的viewmodel,实现方法都是自己写的。而这一个直接使用的表定义的model.model的实现是这样的:

public partial class ExamList    {        [DisplayName("考试主表GID"), StringLength(50)]        public string ExamMainGID { getset; }        [DisplayName("题库与类别关系表的GID"), StringLength(50)]        public string QuestionsLibraryAndSortGid { getset; }        [DisplayName("考试题在题库中的GID"), StringLength(50)]        public string QuestionLibraryGID { getset; }         [DisplayName("考生答案"), StringLength(50)]        public string StudentAnswer { getset; }        /// <summary>        /// 考生答案与正确答案相比是对是错,正确为yes,错误为no        /// </summary>        [DisplayName("是否正确答案"), StringLength(50)]        public string IfRightAnswer { getset; }        [DisplayName("选项顺序"), StringLength(500)]        public string OptionSequence { getset; }        [ForeignKey("QuestionLibraryGID")]        public virtual QuestionsLibrary QuestionsLibrary { getset; }     }

这个表要说有什么不同,也就是最后一行了。它定义了一个外关键字,根据这个外关键字关联了另一张表QuestionsLibrary。是否是这里的问题还需要进行测试。首先我进行了尝试,页面中的相关代码如下:

@{   int i = 0;   foreach (var item in Model)   {      i++;      <div class="pointbox pointboxnull" id="@item.QuestionsLibrary.IID" data-gid="@item.QuestionsLibraryAndSortGid" data-type="@item.QuestionsLibrary.Type" data-sequence="@item.OptionSequence">@i<span></span></div>   }}


我把这行代码:

 <div class="pointbox pointboxnull" id="@item.QuestionsLibrary.IID" data-gid="@item.QuestionsLibraryAndSortGid" data-type="@item.QuestionsLibrary.Type" data-sequence="@item.OptionSequence">@i<span></span></div>

修改为:

<div class="pointbox pointboxnull"   data-gid="@item.QuestionsLibraryAndSortGid" data-sequence="@item.OptionSequence">@i<span></span></div>

就是在循环中不读取QuestionsLibrary表中的内容。然后刷新,没错误了。看来就是外关键字关联的问题。至于如何出现深层entityframework机制,我目前没有时间研究。暂且搁置,采用另一种方法来避免这个错误。

当然不会是重建一个viewmodel,然后重写一个读取方法,这个太费时。actionresult最后的代码是这样实现的:

var list = new ExamListService().Get(m => m.ExamMainGID == examMainGid).OrderBy(m => m.IID); return View(list);

返回的是一个IQueryable对象。cshtml页面顶部的实现代码如下:

@model IQueryable<LMSoft.TrafficRulesTraining.Models.ExamList>

修改后的代码如下:

var list = new ExamListService().Get(m => m.ExamMainGID == examMainGid).OrderBy(m => m.IID);

​return View(list.ToList());

cshtml页面中顶部实现:

@model List<LMSoft.TrafficRulesTraining.Models.ExamList>

编译执行,没有这个错误了,问题解决。

0 0
原创粉丝点击