Extract the Linq query from an IQueryable<T>?
我继承了一个应用程序,并试图调试在我之前编写的实体框架6中运行的一个查询的结果中缺少字段的原因。
原始开发人员创建了一个系统,该系统接受实体上下文、过滤器lambda表达式、按限制排序和包含的属性。为了让我处理查询以查看缺少的内容,我想从IQueryable中提取Linq/lambda查询,该IQueryable在函数末尾放在一起,以便在LinqPad中执行它。
理想情况下,我希望看到"从xtable.include中选择x"("someothertable")。在哪里(谓词)"拼凑在一起?我知道如何查看生成的SQL,但这对确定需要更改的参数没有多大帮助。
功能如下。在应用skip/take/toarray/tolist之前,我基本上需要在两个返回语句之一中使用end linq语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | protected override IEnumerable<T> GetPagedEntity(MyDBContext entityContext, int skip, int take, System.Linq.Expressions.Expression<Func<T, bool>> filter, string orderBy, string includeProperties, out int count) { IQueryable<T> query = entityContext.Set<T>(); string[] orderby = !string.IsNullOrEmpty(orderBy) ? orderBy.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) : null; if (filter != null) { query = query.Where(filter); } count = query.Count(); if (!string.IsNullOrEmpty(includeProperties)) { foreach (var includeProperty in includeProperties.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { query = query.Include(includeProperty); } } if (!string.IsNullOrWhiteSpace(orderBy) && orderby != null && orderby.Length > 0) { for (int i = 0; i < orderby.Length; i++) { if (i == 0) { if (orderby[i].ToLower().Contains(" desc")) { query = FilterExpressionUtil.OrderByDescending(query, orderby[i].Trim().Split(' ')[0]); } else { query = FilterExpressionUtil.OrderBy(query, orderby[i].Trim()); } } else { if (orderby[i].ToLower().Contains(" desc")) { query = FilterExpressionUtil.ThenByDescending(query as IOrderedQueryable<T>, orderby[i].Trim().Split(' ')[0]); } else { query = FilterExpressionUtil.ThenBy(query as IOrderedQueryable<T>, orderby[i].Trim()); } } } return query.Skip(skip).Take(take).ToArray().ToList(); } else { return query.OrderBy(a => 1).Skip(skip).Take(take).ToArray().ToList(); } } |
据我所见,确实没有太多的提取工作要做,因为很多提取工作正在被传递。
1 | IQueryable<T> query = entityContext.Set<T>(); |
正在给您传递的T类型的整个dbset。(我建议对其使用
1 2 3 4 | if (filter != null) { query = query.Where(filter); } |
此代码中没有"where"子句,它正通过
1 2 3 4 5 6 7 8 | if (!string.IsNullOrEmpty(includeProperties)) { foreach (var includeProperty in includeProperties.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { query = query.Include(includeProperty); } } |
此代码中也没有"include"子句,它正在传递给函数。
下一个大模块是处理"orderby"的东西,并返回
对于此函数的每个不同调用,您的问题的答案都会有所不同。
例如:
1 2 3 4 5 6 7 8 9 | GetPagedEntity<User>( entityContext:declaredContext, skip:20, take:40, filter: (u => u.IsActive == true), orderBy:"FirstName,LastName", includeProperties:"table1,table2", out count:declaredInt ) |
看起来像这样:
1 | declaredContext.Set<User>().Where(u => u.IsActive == true).Include("table1").Include("table2").OrderBy(u => u.FirstName).ThenBy(u => u.LastName).Skip(20).Take(40).ToArray().ToList(); |
输出参数
您所要做的就是放置一个断点并对查询变量执行快速监视。您也可以使用LINQ查询。
下面的示例显示生成的LINQ查询。