项目中遇到一个问题,利用linq to datatable查询得到一个query,截止到红色代码部分时,一切都正常,只要一运行query.where 就会报异常:列“SingDate”不属于列表,查看了半天都不知道是为什么,下面是原来的代码:
1 var query = from r in deptName.AsEnumerable() 2 select new 3 { 4 BizDept = r.Field<string>("DEP_NAME"), 5 BizDeptNO = r.Field<string>("DEP_NO"), 6 TotalNum = (from item in dt.AsEnumerable() 7 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 8 select item).ToList().Count(), 9 TotalNumEnd = (from item in dt.AsEnumerable() 10 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 11 && item.Field<DateTime>("SingDate").ToString("yyyy-MM") == temEnd 12 select item).ToList().Count(), 13 TotalMainAmount = (from item in dt.AsEnumerable() 14 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 15 && item.Field<string>("MainID") == null 16 select new { tm = item.Field<decimal>("Amount") }).Sum(p => p.tm) * Convert.ToDecimal(0.00001), 17 TotalMainAmountEnd = (from item in dt.AsEnumerable() 18 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 19 && item.Field<string>("MainID") == null && item.Field<DateTime>("SingDate").ToString("yyyy-MM") == temEnd 20 select new { tm = item.Field<decimal>("Amount") }).Sum(p => p.tm) * Convert.ToDecimal(0.00001), 21 TotalSubAmount = (from item in dt.AsEnumerable() 22 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 23 && item.Field<string>("MainID") != null 24 select new { tm = item.Field<decimal>("Amount") }).Sum(p => p.tm) * Convert.ToDecimal(0.00001), 25 TotalSubAmountEnd = (from item in dt.AsEnumerable() 26 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 27 && item.Field<string>("MainID") != null && item.Field<DateTime>("SingDate").ToString("yyyy-MM") == temEnd 28 select new { tm = item.Field<decimal>("Amount") }).Sum(p => p.tm) * Convert.ToDecimal(0.00001), 29 TotalAmount = (from item in dt.AsEnumerable() 30 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 31 select new { tm = item.Field<decimal>("Amount") }).Sum(p => p.tm) * Convert.ToDecimal(0.00001), 32 TotalAmountEnd = (from item in dt.AsEnumerable() 33 where item.Field<string>("BizDeptNO") == r.Field<string>("DEP_NO") 34 && item.Field<DateTime>("SingDate").ToString("yyyy-MM") == temEnd 35 select new { tm = item.Field<decimal>("Amount") }).Sum(p => p.tm) * Convert.ToDecimal(0.00001) 36 }; 37 var tem = query.ToList(); 38 dt = DataTableHelper.ToDataTable(tem); 39 if (string.IsNullOrWhiteSpace(dept)) 40 { 41 DataRow dr = dt.NewRow(); 42 dr["BizDept"] = "合计"; 43 dr["BizDeptNO"] = ""; 44 dr["TotalNum"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalNum); 45 dr["TotalNumEnd"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalNumEnd); 46 dr["TotalMainAmount"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalMainAmount); 47 dr["TotalMainAmountEnd"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalMainAmountEnd); 48 dr["TotalSubAmount"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalSubAmount); 49 dr["TotalSubAmountEnd"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalSubAmountEnd); 50 dr["TotalAmount"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalAmount); 51 dr["TotalAmountEnd"] = query.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalAmountEnd); 52 dt.Rows.InsertAt(dr, dt.Rows.Count - 1); 53 }
最终,用query.ToList()代替类query,再进行计算,这个错误才消失,即:query.ToList().Where(……)!也就是像下面这样修改代码
1 var tem = query.ToList(); 2 dt = DataTableHelper.ToDataTable(tem); 3 if (string.IsNullOrWhiteSpace(dept)) 4 { 5 DataRow dr = dt.NewRow(); 6 dr["BizDept"] = "合计"; 7 dr["BizDeptNO"] = ""; 8 dr["TotalNum"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalNum); 9 dr["TotalNumEnd"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalNumEnd); 10 dr["TotalMainAmount"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalMainAmount); 11 dr["TotalMainAmountEnd"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalMainAmountEnd); 12 dr["TotalSubAmount"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalSubAmount); 13 dr["TotalSubAmountEnd"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalSubAmountEnd); 14 dr["TotalAmount"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalAmount); 15 dr["TotalAmountEnd"] = tem.Where(p => p.BizDeptNO != "0118").Sum(p => p.TotalAmountEnd); 16 dt.Rows.InsertAt(dr, dt.Rows.Count - 1); 17 }
难道说,直接再次调用query.Where,之前的查询(var query=……),还会默认执行一次么?
为了验证,我把SingDate字段设置成常量,再次运行,果然又报异常了,这次是其他的列不属于表,还真是,再次调用query.where, 原来的查询还会默认执行一遍!但问题又来了,就算再执行一遍,我的数据源不应该一直有数据么,怎么会找不到列了呢?难道数据源也改变了?这个问题,暂时记下,有时间继续研究研究。
如果哪位大哥知道原因,一定告诉小弟,先谢谢了!