从IQueryable <t>中提取Linq查询?

时间:2015-04-24 02:29:51

标签: c# linq entity-framework lambda

我继承了一个应用程序,并且正在尝试调试为什么在我之前编写的实体框架6中运行的其中一个查询的结果中缺少某个字段。

原始开发人员创建了一个系统,该系统接受实体上下文,过滤器Lambda表达式,按限制排序和包含的属性。为了让我使用查询来查看缺少的内容,我想从函数末尾放在一起的IQueryable中提取Linq / Lambda查询,以便在Linqpad中执行它。

理想情况下,我希望看到什么样的“从XTable.Include(”SomeOtherTable“)选择x。哪里(谓词)拼凑在一起?我知道如何查看生成的SQL,但这对于确定需要更改的参数没有多大帮助。

这是功能。在应用Skip / Take / ToArray / ToList之前,我基本上需要在两个return语句之一中使用end linq语句。

    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();
        }
    }

2 个答案:

答案 0 :(得分:0)

您所要做的就是放置一个断点并对查询变量进行快速监视。你也可以查询linq。

下面的示例显示了生成的LINQ查询。

enter image description here

答案 1 :(得分:0)

从我所看到的情况来看,实际上并没有多少工作要做,因为很多工作都被传入。

IQueryable<T> query = entityContext.Set<T>();

正在为您提供您传入的T类型的整个DBSet。(我建议在其上设置where T : DbSet类型约束,不确定这是否是确切的语法,但请确保您只能通过在entityContext(第一个参数)知道的类型中。

if (filter != null)
        {
            query = query.Where(filter);
        }

没有&#34; Where&#34;在这段代码中,它被传递给带有System.Linq.Expressions.Expression<Func<T, bool>> filter参数的函数。

if (!string.IsNullOrEmpty(includeProperties))
        {
            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }
        }

没有&#34;包括&#34;在这段代码中的子句,它被传递给函数。

下一个重点是处理&#34; OrderBy&#34;这些内容正在返回IEnumerable<T>Skip(skip).Take(take).ToArray().ToList();加到最后。

对于此功能的每次不同调用,您的问题的答案都会有所不同。

例如:

GetPagedEntity<User>(
entityContext:declaredContext, 
skip:20, 
take:40, 
filter: (u => u.IsActive == true), 
orderBy: "FirstName,LastName", 
includeProperties: "table1,table2", 
out count:declaredInt
)

看起来像这样:

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();

输出参数count将在Take方法获取指定数量之前返回计数。希望这有帮助,对不起,如果我的语法稍微偏离。