问题描述
如下面函数看,这是第一种写法TeachEasEntitiesdb=newTeachEasEntities(Public.Dbase.DataBaseEFConn);privateIEnumerable<exam_Batch>ExamBatch_GetList(stringyearTermID,stringexamWeek,stringweekSection){stringweekSection2=weekSection;if(weekSection.Substring(1)=="1"||weekSection.Substring(1)=="3")weekSection2=(int.Parse(weekSection)+1).ToString();varquery=fromrindb.exam_Batchwherer.YearTermID==yearTermID&&r.ExamWeek==examWeek&&((r.WeekSection==weekSection&&r.WeekTime==2)||((r.WeekSection==weekSection2||r.WeekSection==weekSection)&&r.WeekTime==3))selectr;returnquery;}publicoverrideIEnumerable<View_All>ExamRoomStudent_GetRoomList(stringyearTermID,stringexamWeek,stringweekSection,stringroomID){varqueryBatch=ExamBatch_GetList(yearTermID,examWeek,weekSection);//获得学生列表varqueryStud=fromrinqueryBatchfromyindb.exam_Roomfromsindb.exam_RoomStudentfromtindb.e_Studentfromqindb.t_TeachTaskwherer.YearTermID==y.YearTermID&&r.BatchOrder==y.BatchOrder&&r.BatchFlag==(byte)ExamBatchInfo.Enum_BatchFlag.Released&&y.ExamRoomID==s.ExamRoomID&&y.YearTermID==q.YearTermID&&y.CourID==q.CourID&&y.CourOrder==q.CourOrder&&s.StudID==t.StudID&&y.RoomID==roomIDselectnew{YearTermID=y.YearTermID,CourID=y.CourID,CourOrder=y.CourOrder,CourName=q.CourName,StudName=t.StudName,ClassName=t.ClassName,StudID=t.StudID,};returnquery;}
这是第二种写法TeachEasEntitiesdb=newTeachEasEntities(Public.Dbase.DataBaseEFConn);publicoverrideIEnumerable<View_All>ExamRoomStudent_GetRoomList(stringyearTermID,stringexamWeek,stringweekSection,stringroomID){stringweekSection2=weekSection;if(weekSection.Substring(1)=="1"||weekSection.Substring(1)=="3")weekSection2=(int.Parse(weekSection)+1).ToString();varqueryBatch=fromrindb.exam_Batchwherer.YearTermID==yearTermID&&r.ExamWeek==examWeek&&((r.WeekSection==weekSection&&r.WeekTime==2)||((r.WeekSection==weekSection2||r.WeekSection==weekSection)&&r.WeekTime==3))selectr;//获得学生列表varqueryStud=fromrinqueryBatchfromyindb.exam_Roomfromsindb.exam_RoomStudentfromtindb.e_Studentfromqindb.t_TeachTaskwherer.YearTermID==y.YearTermID&&r.BatchOrder==y.BatchOrder&&r.BatchFlag==(byte)ExamBatchInfo.Enum_BatchFlag.Released&&y.ExamRoomID==s.ExamRoomID&&y.YearTermID==q.YearTermID&&y.CourID==q.CourID&&y.CourOrder==q.CourOrder&&s.StudID==t.StudID&&y.RoomID==roomIDselectnew{YearTermID=y.YearTermID,CourID=y.CourID,CourOrder=y.CourOrder,CourName=q.CourName,StudName=t.StudName,ClassName=t.ClassName,StudID=t.StudID,};returnquery;}
其实第一种写法就是将下面这段单独拿出来作为一个独立的函数stringweekSection2=weekSection;if(weekSection.Substring(1)=="1"||weekSection.Substring(1)=="3")weekSection2=(int.Parse(weekSection)+1).ToString();varqueryBatch=fromrindb.exam_Batchwherer.YearTermID==yearTermID&&r.ExamWeek==examWeek&&((r.WeekSection==weekSection&&r.WeekTime==2)||((r.WeekSection==weekSection2||r.WeekSection==weekSection)&&r.WeekTime==3))selectr;
看起来没有什么不同,但当你实际执行的时候,你会发现,第二种写法在数据库只执行了一次,而第一种写法根据你的数据量执行了N次。为了这个EF的函数复用,我已经想了很多办法了,但无论如何也没有什么好的办法。第一种方法中的函数也并没有ToList()什么的,但就是没法像第二个那样。。。。。求教啊,难道必须一个函数写一遍LINQ语句吗?没有办法复用吗?第一个独立出来的函数不是没有执行吗?为什么要这样虐待我啊。。。。。
解决方案
解决方案二:
把第一种写法的第一个函数的返回类型改为IQueryable<exam_Batch>就行了
解决方案三:
本来ObjectContext默认返回的就是IQueryable<T>这种不执行的查询但是因为你把返回类型定义为IEnumrable<T>了,而IQueryable<T>:IEnumrable<T>,导致方法上看起来,但实际运行的时候,后者是会展开枚举(执行查询)的,而前者却不会,只代表一串查询表达式
解决方案四:
返回类型为IQueryable
解决方案五:
这个反复发帖终归是不好的……
解决方案六:
引用2楼dongxinxi的回复:
本来ObjectContext默认返回的就是IQueryable<T>这种不执行的查询但是因为你把返回类型定义为IEnumrable<T>了,而IQueryable<T>:IEnumrable<T>,导致方法上看起来,但实际运行的时候,后者是会展开枚举(执行查询)的,而前者却不会,只代表一串查询表达式
谢谢,我试试。
解决方案七:
最大的原因是你为什么不用视图呢,把四个需要的条件字段放在一个视图里不就解决问题了吗。
解决方案八:
还有那TeachEasEntities最好不要声明为类变量,这个对象很大,我也没有看见你手动释放的地方,很容易产生性能问题。