C# 实体框架:将分页与动态LINQ OrderBy相结合

C# 实体框架:将分页与动态LINQ OrderBy相结合,c#,entity-framework,linq,dynamic-linq,C#,Entity Framework,Linq,Dynamic Linq,我正在使用实体框架检索一些数据,如下所示: var items = GetItems(storeNumber); Sort(items); Page(items); return await items.ToListAsync(); 我有以下私人助手方法: private IQueryable<Item> GetItems(string storeNumber) { return _dbContext.Items.Where(x => x.StoreNumber

我正在使用实体框架检索一些数据,如下所示:

var items = GetItems(storeNumber);

Sort(items);

Page(items);

return await items.ToListAsync();
我有以下私人助手方法:

private IQueryable<Item> GetItems(string storeNumber)
{
    return _dbContext.Items.Where(x => x.StoreNumber == storeNumber);
}
private IQueryable GetItems(字符串storeNumber)
{
返回_dbContext.Items.Where(x=>x.StoreNumber==StoreNumber);
}
我使用动态LINQ对结果进行排序

private void Sort(IQueryable<Item> items, string fieldToSort, string sortDirection)
{
    items = items.OrderBy($"{fieldToSort} {sortDirection}");
}
private void排序(IQueryable项、字符串字段排序、字符串排序方向)
{
items=items.OrderBy($“{fieldToSort}{sortDirection}”);
}
在我的Page方法中,我得到了异常

方法“OrderBy”必须在方法“Skip”之前调用

private void页(IQueryable项、int skip、int take)
{
items=items.Skip(Skip).Take(Take);
}
我怀疑出现错误的原因是因为项目需要是
IOrderedQueryable
,但是动态LINQ OrderBy没有重载,它返回
IOrderedQueryable
。 如果我使用
var
将Sort和Page代码提取到同一个方法中,这不再是一个问题,它会推断出类型。问题似乎是在排序和分页时使用
IQueryable
接口。有没有一种方法可以将此逻辑分解为单独的方法,但仍然使用动态LINQ进行排序


非常感谢您的帮助。

您应该从Sort()和Page()方法返回新构造的
IQueryable
,就像您对GetItems()所做的一样。 如果在这样的方法中“重写”参数值,它对最初传入参数的值没有影响,因为C#使用按值参数传递语义

有关更多参考信息,请参见:

这个问题要琐碎得多。目前,
排序
方法(以及
页面
和任何LINQ方法)无效,因为您没有使用应用的可查询运算符返回结果。考虑将它们更改为返回<代码> iQueEdaby<代码>的方法,例如<代码>私有IQueryable Sort(…){返回项。OrderBy(…);}。我也不会忘记使用返回的结果。@IvanStoev该方法是void的,但我正在传递项作为引用,不是吗?我正在将项目设置为扩展查询。也许我搞糊涂了?您正在将对对象的引用传递到items中(在您的方法中,items是一个局部变量)。然后更改项(仍然是局部变量),然后方法结束。要实现您想要的(=更改外部项),您需要使用
ref IQueryable items
,或者需要返回局部变量
items
。使用
return…
是目前最常用的方法。是的,您可以将它们作为引用传递。但所有LINQ方法都不会修改
IQueryable
引用。相反,它们返回一个需要使用的新引用。如果你是指在 Value方法中指定<>代码>项目< /代码>变量,你可以考虑阅读关于<代码> > REF参数的C语言。是的,你很困惑。排序函数不会对序列进行排序,它只会用新查询替换变量项。由于您的4变量既不是ref,也不是out,因此调用方提供的items对象不会更改。如果您没有替换变量项,而是更改了items的属性,则情况会有所不同。我正在将items作为对Sort和Page方法的引用传递,或者我可能感到困惑?IQueryable确实是一个接口,因此它是一个引用类型,但您没有通过引用传递参数。这两者是不相关的:可以通过值传递引用类型(默认语义),也可以通过引用传递。您正在按值传递引用类型(因此基本上是内存地址)(因此分配一个新块并复制引用,但在执行赋值时旧块保持不变)。有关详细信息,请参见此文档示例:
private void Page(IQueryable<Item> items, int skip, int take)
{
    items = items.Skip(skip).Take(take);
}