我正在阅读通用存储库。我一直磕磕绊绊地谈论一些我不理解的代码。我不知道他们是否有特定名称。
这是我见过的最复杂的例子:
IEnumerable<T> GetByQuery(
Expression<Func<T, bool>> query = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderby = null,
string includeProperties = "");
我知道(无论它是什么)显然会返回IEnumerable
,但我不知道如何阅读那些混乱的gobbledygook,更不用说如何使用它了。
编辑:我更有兴趣了解的 ,而不是该特定示例的细分。在找到解释语法的东西之前,我需要知道他们调用了什么。 LINQ?
编辑2:我提出了一个比回答问题更简单的问题。我想知道的是&#34;我可以用什么搜索词来研究上面的代码?&#34;
答案 0 :(得分:9)
请注意,根据IQueryable<T>
的工作原理,所有这些都是极其有根据的猜测。
将其分解为三个部分:
Expression<Func<T, bool>> query = null
这是一个where子句,它与Where
上传递给IQueryable<T>
扩展方法的签名相同。
你传递一个表达式,它在代码中的表示方式与lambda相同; C#编译器知道该参数正在查找Expression
并将其编译为表达式树而不是委托。
例如,假设T
是具有Person
属性int
的{{1}}类,则可以过滤掉{{1}返回的任何Age
以下是30岁或以上:
Person
IQueryable<Person>
这只是一个代表,如果提供,将允许您设置订单。假设您希望按年龄排序p => p.Age > 30
个实例,您可以使用:
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy
这是因为返回类型为Person
,只有在您调用q => q.OrderBy(p => p.Age)
和IOrderedQueryable<T>
后才会弹出ThenBy
和ThenByDescending
等扩展方法;这些扩展方法仅在OrderBy
上定义(它只是一个标记接口)。
OrderByDescending
这表明它正在使用幕后的实体框架。当您在实体框架中调用IOrderedQueryable<T>
时,它允许您获取相关实体(通过外键)并加载与查询中返回的实体相关的实体。
假设includeProperties
类的属性Include
类型为Person
。如果您想查询Father
个实例并且还返回了Person
属性,那么您将调用Person
来指示实体框架不仅应该获取{{1}的实例},但它也应该解决Father
关系。
Include("Father")
返回类型
返回此项,以便您无权访问Person
实例,并强制您实现结果集(当您迭代它时)。
执行此操作的实现应该返回一个实体化列表(Father
),或者不仅仅是(假设)是IEnumerable<T>
到{{{ 1}}。
这也表明了该方法的作者对客户的信任;如果未返回IQueryable<T>
,则表示它不信任客户端不进行低效的数据库调用(这是一个有效的问题)。