引子
平台表格样式如上:我们在开发这种表格的时候,会经常进行增、删、改查操作,所以就经常会有数据库的操作,数据库链路层ORM映射是使用的EF组件,如下的表格,我们在后台更经常是用的IList(List)承载,所以也经常会有List等数据集合的操作。
起因
最近在开发一个地产软件项目,我们在开发过程中开发了很多的表格,页面初始加载数据时,如下表格所示:
过程
做好表格后,传送数据给后台,后台代码进行处理,由于我们有对表格进行增、删、改的操作,所以在后台代码也进行相关的逻辑处理,一开始我们的代码如下:
var currCBFYJSCSList = currentObject.CBFYJSCSList.Where(t => t.IsDelete == false).ToList(); if (currentObject != null && currentObject.CBFYJSCSList != null && currCBFYJSCSList.Count > 0) { var deleteDetails = currCBFYJSCSList.Except(paraconfig.CBFYJSCSList, new ListEqualityCBFYJSCS()).ToList(); if (deleteDetails != null && deleteDetails.Count > 0) { deleteDetails.ForEach(t => t.IsDelete = true);//软件平台代码浏览 } } if (paraconfig != null && paraconfig.CBFYJSCSList != null) { var addDetails = paraconfig.CBFYJSCSList.Except(currCBFYJSCSList, new ListEqualityCBFYJSCS()).ToList(); addDetails.ForEach(a => { a.Id = 0; a.ParaConfigID = currentObject.Id; currCBFYJSCSList.Add(a); }); } if (paraconfig != null && paraconfig.CBFYJSCSList != null && currentObject != null && currentObject.CBFYJSCSList != null) { var updateDetails = currentObject.CBFYJSCSList.Intersect(paraconfig.CBFYJSCSList, new ListEqualityCBFYJSCS()).ToList(); if (updateDetails != null && updateDetails.Count > 0) { updateDetails.ForEach(f => { CBFYJSCS fcdnew = paraconfig.CBFYJSCSList.Where(t => t.Id == f.Id).FirstOrDefault(); if (fcdnew != null) { CommonHelper.CopyModel(fcdnew, f, false, "ParaConfig"); } }); } } CommonHelper.CopyModel(paraconfig, currentObject);//开发框架模型复制调用代码 currentObject.ModifyBy = this.CurrentUser.LoginAccount; currentObject.ModifyAt = DateTime.Now; _paraconfigService.UpdateParaConfig(currentObject);
现象
我们在最后一步更新保存的时候,确实也可以保存成功,我再刷新页面加载保存后数据,发现数据根本就没变,是保存失败的,如下图:
缘由
既然用的EF,那肯定是EF工作不到位,那是什么原因呢,
我们查了很多资料,EF是有数据跟踪的,如果给它的不是原跟踪的数据集合,那肯定是保存不了的,大家注意看我们的代码的第一行:
最终保存和更新的是currCBFYJSCSList,可是这个currCBFYJSCSList再也不是原来的那个currCBFYJSCSList了,这个才是导致问题的根本。
那怎么去解决呢?其实很简单,去掉后面的.ToList()就可以了,为什么呢,大家查下.ToList()里面究竟干了什么,反正不是好事,至少对于这段代码来说,.ToList()后返回是 一个全新的引用类型对象,这个对EF来说就是陌生人咯!
var currCBFYJSCSList = currentObject.CBFYJSCSList.Where(t => t.IsDelete == false).ToList();
解决