C# 有没有一种方法可以通过不同订购量的IQueryable进行订购
例如,我想试试这样的东西。排序PAR可能没有,1个或多个排序列按不同顺序排列。但是我不能使用C# 有没有一种方法可以通过不同订购量的IQueryable进行订购,c#,linq,entity-framework,sql-order-by,C#,Linq,Entity Framework,Sql Order By,例如,我想试试这样的东西。排序PAR可能没有,1个或多个排序列按不同顺序排列。但是我不能使用ThenBy方法,因为它只在OrderBy之后才可用。下面的代码将继续将订单重置为排序列表中的最后一项。我也不想更改方法签名。非常感谢您的帮助,谢谢 public IQueryable<Person> FilterList(string forename, List<Sorting> sorting) { IQueryable<Person> query = d
ThenBy
方法,因为它只在OrderBy
之后才可用。下面的代码将继续将订单重置为排序列表中的最后一项。我也不想更改方法签名。非常感谢您的帮助,谢谢
public IQueryable<Person> FilterList(string forename, List<Sorting> sorting)
{
IQueryable<Person> query = dc.Set<Person>();
if(!string.IsNullOrEmpty(forename)){
query = query.Where(w=>w.Forename.Contains(forename));
foreach(var sort in sorting)
{
switch(sort.By)
{
case "asc":
switch(sort.Sort)
{
case "forename":
query = query.OrderBy(o=>o.Forename);
break;
case "surname":
query = query.OrderBy(o=>o.Surname);
break;
}
break;
case "desc":
switch(sort.Sort)
{
case "forename":
query = query.OrderByDescending(o=>o.Forename);
break;
case "surname":
query = query.OrderByDescending(o=>o.Surname);
break;
}
break;
}
}
return query;
}
public class Sorting
{
public string Sort{get;set;}
public string By{get;set;}
}
publicIQueryable过滤器列表(字符串名,列表排序)
{
IQueryable query=dc.Set();
如果(!string.IsNullOrEmpty(forename)){
query=query.Where(w=>w.Forename.Contains(Forename));
foreach(排序中的变量排序)
{
开关(按排序)
{
案例“asc”:
开关(sort.sort)
{
案例“forename”:
query=query.OrderBy(o=>o.Forename);
打破
“姓氏”一案:
query=query.OrderBy(o=>o.lasname);
打破
}
打破
案例“desc”:
开关(sort.sort)
{
案例“forename”:
query=query.OrderByDescending(o=>o.Forename);
打破
“姓氏”一案:
query=query.OrderByDescending(o=>o.姓氏);
打破
}
打破
}
}
返回查询;
}
公共类排序
{
公共字符串排序{get;set;}
由{get;set;}生成的公共字符串
}
您可能需要使用cast:
var sortedQueryable = query as IOrderedQueryable<Person>;
if (sortedQueryable != null)
{
query = sortedQueryable.ThenBy(o => o.Forename);
}
else
{
query = query.OrderBy(o => o.Forename);
}
因此,在您的
foreach
循环中,您只需要if
forSortMode
并将元组的Item2
传递给订购方。您可能需要使用cast:
var sortedQueryable = query as IOrderedQueryable<Person>;
if (sortedQueryable != null)
{
query = sortedQueryable.ThenBy(o => o.Forename);
}
else
{
query = query.OrderBy(o => o.Forename);
}
因此,在您的
foreach
循环中,您只需要如果forSortMode
并将元组的Item2
传递给排序者。首先按常量排序,这样您就有了一个IOrderedQueryable
,然后您就可以通过然后按方法进行所有自定义排序
public IQueryable<Person> FilterList(string forename, List<Sorting> sorting) {
IQueryable<Person> query = dc.Set<Person>();
if(!string.IsNullOrEmpty(forename)){
query = query.Where(w=>w.Forename.Contains(forename));
var orderedQuery = query.OrderBy(x => 1);
foreach(var sort in sorting) {
switch(sort.By) {
case "asc":
switch(sort.Sort) {
case "forename":
orderedQuery = orderedQuery.ThenBy(o=>o.Forename);
break;
case "surname":
orderedQuery = orderedQuery.ThenBy(o=>o.Surname);
break;
}
break;
case "desc":
switch(sort.Sort) {
case "forename":
orderedQuery = orderedQuery.ThenByDescending(o=>o.Forename);
break;
case "surname":
orderedQuery = orderedQuery.ThenByDescending(o=>o.Surname);
break;
}
break;
}
}
return orderedQuery;
}
publicIQueryable过滤器列表(字符串名,列表排序){
IQueryable query=dc.Set();
如果(!string.IsNullOrEmpty(forename)){
query=query.Where(w=>w.Forename.Contains(Forename));
var orderedQuery=query.OrderBy(x=>1);
foreach(排序中的变量排序){
开关(按排序){
案例“asc”:
开关(sort.sort){
案例“forename”:
orderedQuery=orderedQuery.ThenBy(o=>o.Forename);
打破
“姓氏”一案:
orderedQuery=orderedQuery.ThenBy(o=>o.姓氏);
打破
}
打破
案例“desc”:
开关(sort.sort){
案例“forename”:
orderedQuery=orderedQuery.ThenByDescending(o=>o.Forename);
打破
“姓氏”一案:
orderedQuery=orderedQuery.ThenByDescending(o=>o.姓氏);
打破
}
打破
}
}
返回订单查询;
}
首先按常量排序,这样您就有了一个IOrderedQueryable
,然后您可以通过然后按方法进行所有自定义排序
public IQueryable<Person> FilterList(string forename, List<Sorting> sorting) {
IQueryable<Person> query = dc.Set<Person>();
if(!string.IsNullOrEmpty(forename)){
query = query.Where(w=>w.Forename.Contains(forename));
var orderedQuery = query.OrderBy(x => 1);
foreach(var sort in sorting) {
switch(sort.By) {
case "asc":
switch(sort.Sort) {
case "forename":
orderedQuery = orderedQuery.ThenBy(o=>o.Forename);
break;
case "surname":
orderedQuery = orderedQuery.ThenBy(o=>o.Surname);
break;
}
break;
case "desc":
switch(sort.Sort) {
case "forename":
orderedQuery = orderedQuery.ThenByDescending(o=>o.Forename);
break;
case "surname":
orderedQuery = orderedQuery.ThenByDescending(o=>o.Surname);
break;
}
break;
}
}
return orderedQuery;
}
publicIQueryable过滤器列表(字符串名,列表排序){
IQueryable query=dc.Set();
如果(!string.IsNullOrEmpty(forename)){
query=query.Where(w=>w.Forename.Contains(Forename));
var orderedQuery=query.OrderBy(x=>1);
foreach(排序中的变量排序){
开关(按排序){
案例“asc”:
开关(sort.sort){
案例“forename”:
orderedQuery=orderedQuery.ThenBy(o=>o.Forename);
打破
“姓氏”一案:
orderedQuery=orderedQuery.ThenBy(o=>o.姓氏);
打破
}
打破
案例“desc”:
开关(sort.sort){
案例“forename”:
orderedQuery=orderedQuery.ThenByDescending(o=>o.Forename);
打破
“姓氏”一案:
orderedQuery=orderedQuery.ThenByDescending(o=>o.姓氏);
打破
}
打破
}
}
返回订单查询;
}
AgentFire的答案实际上是恰当的,但在每种情况下,对于特殊情况都有点冗长。我要添加一个扩展方法:
编辑:显然,下面的代码无法正确确定查询是否已排序;即使是无序版本也显然实现了IOrderedQueryable
。使用source.Expression.Type
检查IOrderedQueryable
显然有效,但我将此代码保留在这里作为更符合逻辑的方法-and因为这个“修复”听起来比我想要一个写着我名字的答案更脆弱:)
这样一来,每个额外的排序选项只会增加一小部分代码开销。AgentFire的答案实际上是合适的,但对于每种情况的特殊情况,都有点冗长。我要添加一个扩展方法:
编辑:显然,下面的代码无法正确确定查询是否已排序;即使是无序版本也显然实现了IOrderedQueryable
。使用source.Expression.Type
检查IOrderedQueryable
显然有效,但我将此代码保留在这里作为更符合逻辑的方法-and因为这个“修复”听起来比我想要一个写着我名字的答案更脆弱:)
这样一来,每个额外的排序选项只会增加很小的代码开销。有很多选项可供选择。例如:
bool isSorted = false;
foreach(var sort in sorting)
{
switch(sort.By)
{
case "asc":
switch(sort.Sort)
{
case "forename":
if (!isSorted)
{
query = query .OrderBy(o => o.Forename);
isSorted = true;
}
else
{
query = ((IOrderedQueryable<Person>)query).ThenBy(o => o.Forename);
}
...
}
break;
case "desc":
...
}
}
bool isSorted=false;
前面
bool isSorted = false;
foreach(var sort in sorting)
{
switch(sort.By)
{
case "asc":
switch(sort.Sort)
{
case "forename":
if (!isSorted)
{
query = query .OrderBy(o => o.Forename);
isSorted = true;
}
else
{
query = ((IOrderedQueryable<Person>)query).ThenBy(o => o.Forename);
}
...
}
break;
case "desc":
...
}
}
public static IOrderedQueryable<T> AddOrdering<T, TKey>(
this IQueryable<T> source,
Expression<Func<T, TKey>> keySelector,
bool descending)
{
// If it's not ordered yet, use OrderBy/OrderByDescending.
if(source.Expression.Type != typeof(IOrderedQueryable<T>))
{
return descending ? source.OrderByDescending(keySelector)
: source.OrderBy(keySelector);
}
// Already ordered, so use ThenBy/ThenByDescending
return descending ? ((IOrderedQueryable<T>)source).ThenByDescending(keySelector)
: ((IOrderedQueryable<T>)source).ThenBy(keySelector);
}
foreach(var sort in sorting)
{
bool descending = sort.By == "desc";
switch (sort.Sort)
{
case "forename":
query = query.AddOrdering(o => o.Forename, descending);
break;
case "surname":
query = query.AddOrdering(o => o.Surname, descending);
break;
}
}