在现有查询中插入Linq查询部分
本文关键字:Linq 查询部 插入 查询 | 更新日期: 2023-09-27 18:06:45
具有以下存储IQueryable
的变量:
var mainQuery = session
.Query<Employee>()
.Select(e => new
{
e.Name,
e.Address
});
和一个以IQueryable作为参数的方法
public DataTable GetData(IQueryable query)
{
...
}
如何在GetData()
中编写代码,将OrderBy()
添加到Select()
之前?
query
的最终值应该看起来像使用以下Linq表达式构建的:
var query = session
.Query<Employee>()
.OrderBy(e => e.Age)
.Select(e => new
{
e.Name,
e.Address
});
这是必需的,因为如果我在Select()
之后添加OrderBy()
,我将只能按匿名类型(名称,地址)的成员排序。如果一个员工也有和年龄,当我把OrderBy()
放在Select()
后面时,我不能按它排序。谢谢你的帮助!
更新:
GetData
不知道查询的结构,只知道它以Select
结尾。它必须有确切的签名public DataTable GetData(IQueryable query)
——没有额外的参数。
如何修改方法内部的现有查询,并在Select
之前添加OrderBy
当有正确答案时,我会接受并投票给它。
为什么不在调用GetData()
之后应用select()
呢?
var mainQuery = session.Query<Employee>();
this.GetData(mainQuery);
mainQuery.OrderBy(x => x.Age)
.Select(x => new
{
x.Name,
x.Address
});
Linq表达式树是不可变的(源)。你必须创建一个部分的树的副本来修改它。
Update:请记住,您的模式正在尝试将数据访问与表示分离(或者至少它是如何读取的)。点菜是一种表现方式。您可能有多个客户端希望使用GetData来获取数据,但每个客户端都可能希望对数据进行不同的排序。无论如何,您的原始查询在调用GetData之后投影,因此使用投影排序是有意义的。
现在,如果你真的想在不改变契约的情况下在方法内部排序,你必须遍历linq查询的表达式树,并从头开始重建它,在正确的位置注入排序。表达式树是不可变的,不能就地修改。
考虑为Employee
创建ViewModel
或DTO
,并且不传递匿名对象。但无论如何,你可以将selector
传递到GetData
,并在Employee
排序后应用它
var mainQuery = session.Query<Employee>();
GetData(mainQuery, e => new { e.Name, e.Address });
//object is used because you create anonymous objects and pass them around
public DataTable GetData(IQueryable query,
Expression<Func<Employee, object>> selector)
{
return query.OrderBy(e => e.Age)
.Select(selector)
//...
}