C# 直接使用多个ThenBy,无需任何订单

C# 直接使用多个ThenBy,无需任何订单,c#,linq,C#,Linq,我试图在LINQ中同时基于多个列进行排序 为了实现这个排序列表,我应该对第一列使用SortBy,然后对另一列使用多个ThenBy对OrderBy的结果进行排序 但问题是,我在使用ThenBy(s)时没有任何顺序,这是因为用户选择第一列,我使用此列作为OrderBy的参数,其余列是ThenBy的参数 我首先声明一个动态全局变量,如: dynamic result; 然后创建一个实体模型,如: DatabaseEntityContext context = new DatabaseEntityCo

我试图在LINQ中同时基于多个列进行排序

为了实现这个排序列表,我应该对第一列使用
SortBy
,然后对另一列使用多个
ThenBy
OrderBy
的结果进行排序

但问题是,我在使用
ThenBy
(s)时没有任何顺序,这是因为用户选择第一列,我使用此列作为
OrderBy
的参数,其余列是
ThenBy
的参数

我首先声明一个动态全局变量,如:

dynamic result;
然后创建一个实体模型,如:

DatabaseEntityContext context = new DatabaseEntityContext();
和查询数据以获得适当的匿名数据类型:

    var query1 = db.context.Select(x => new { Column1 = x.Column1, Column2 = x.Column2,
 Column3 = x.Column3, Column4 = x.Column4, Column5 = x.Column5 }).ToList();

    var query2 = query1.Select(x => new { Column1 = x.Column1, Column2 = x.Column2,
 Column3 = x.Column3, TotalColumn = x.Column4 + "-" + x.Column5 }).ToList();
最后将
query2
分配给
result
如下:

result = query2;
result = ((IOrderedQueryable<dynamic>)result).ThenBy(x => x.MyDynamicField).ToList();
要在
result
上使用LINQ函数,我将其转换为
((IEnumerable)result)
但问题是此强制转换的结果没有任何
ThenBy
扩展,我不能首先使用
OrderBy
,因为列表可能已经按另一列排序,我应该使用
ThenBy
根据之前排序的列表的结果再次排序

我的问题是,我在
ThenBy
中使用了多个因素,但我不能对其进行排序,因为我应该先使用
OrderBy
,然后在
OrderBy
之后使用
ThenBy
,我不能直接使用
ThenBy

那么,我如何才能将
ThenBy
直接用于先前排序的列表

更新1: 根据@Patrick Hofman,我将我的演员类型更改为
IOrderedQueryable
如下:

result = query2;
result = ((IOrderedQueryable<dynamic>)result).ThenBy(x => x.MyDynamicField).ToList();
result=((IOrderedQueryable)result)。然后按(x=>x.MyDynamicField.ToList();
但是没有,它在
“x.MyDynamicField”
上给了我一个编译错误:

表达式树不能包含动态操作

我还测试了
IOrderedEnumerable
,但它给出了
InvalidCastException
错误:

无法强制转换类型为的对象 'System.Collections.Generic.List
1[f_uAnonymousType1
5[System.String,System.String,System.DateTime,System.TimeSpan,System.Nullable
1[System.Int32]]
输入'System.Linq.IOrderedEnumerable
1[System.Object]'


ThenBy
是对
IOrderedQueryable
的扩展方法,而不是
IEnumerable
。如果要调用
,则应将其强制转换为
IOrderedQueryable

var r = ((IOrderedQueryable<dynamic>)result).ThenBy(...);
var r=((IOrderedQueryable)结果),然后按(…);

正如juharr所评论的,您甚至可以扩展它来检查类型,然后选择
ThenBy
OrderBy
,使用相同的谓词进行筛选。

ThenBy
IOrderedQueryable
的扩展方法,而不是
IEnumerable
。如果要调用
,则应将其强制转换为
IOrderedQueryable

var r = ((IOrderedQueryable<dynamic>)result).ThenBy(...);
var r=((IOrderedQueryable)结果),然后按(…);

正如juharr所评论的那样,您甚至可以扩展它来检查类型,然后选择
ThenBy
OrderBy
,使用相同的谓词进行筛选。

而不是使用
OrderBy
/
ThenBy
,您可以:

public static class QueryableOrderBy
{
    public static IOrderedQueryable<TSource> OrderBySimple<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
    {
        var ordered = source as IOrderedQueryable<TSource>;

        if (source != null)
        {
            return ordered.ThenBy(keySelector);
        }

        return source.OrderBy(keySelector);
    }

    public static IOrderedQueryable<TSource> OrderByDescendingSimple<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
    {
        var ordered = source as IOrderedQueryable<TSource>;

        if (source != null)
        {
            return ordered.ThenByDescending(keySelector);
        }

        return source.OrderByDescending(keySelector);
    }
}
公共静态类QueryableOrderBy
{
公共静态IOrderedQueryable OrderBySimple(此IQueryable源、表达式键选择器)
{
var ordered=源作为IOrderedQueryable;
如果(源!=null)
{
已订购退货。然后由(按键选择器);
}
返回source.OrderBy(keySelector);
}
公共静态IOrderedQueryable OrderByDowningSimple(此IQueryable源、表达式键选择器)
{
var ordered=源作为IOrderedQueryable;
如果(源!=null)
{
按顺序返回。然后按降序(键选择器);
}
返回source.OrderByDescending(keySelector);
}
}

这些方法将“分析”是否存在另一个
OrderBy
(然后使用
ThenBy
)。

而不是使用
OrderBy
/
ThenBy
,您可以:

public static class QueryableOrderBy
{
    public static IOrderedQueryable<TSource> OrderBySimple<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
    {
        var ordered = source as IOrderedQueryable<TSource>;

        if (source != null)
        {
            return ordered.ThenBy(keySelector);
        }

        return source.OrderBy(keySelector);
    }

    public static IOrderedQueryable<TSource> OrderByDescendingSimple<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
    {
        var ordered = source as IOrderedQueryable<TSource>;

        if (source != null)
        {
            return ordered.ThenByDescending(keySelector);
        }

        return source.OrderByDescending(keySelector);
    }
}
公共静态类QueryableOrderBy
{
公共静态IOrderedQueryable OrderBySimple(此IQueryable源、表达式键选择器)
{
var ordered=源作为IOrderedQueryable;
如果(源!=null)
{
已订购退货。然后由(按键选择器);
}
返回source.OrderBy(keySelector);
}
公共静态IOrderedQueryable OrderByDowningSimple(此IQueryable源、表达式键选择器)
{
var ordered=源作为IOrderedQueryable;
如果(源!=null)
{
按顺序返回。然后按降序(键选择器);
}
返回source.OrderByDescending(keySelector);
}
}

这些方法将“分析”是否存在另一个
OrderBy
(然后使用
ThenBy
)。

听起来您需要确定您的
结果是
IEnumerable
还是
IORDerenumerable
。但这很难说。如果你的意思是排序是在
ToList
之前完成的,那么我不想告诉你,但是你必须在添加加法
然后通过
调用之前再次进行排序。听起来你需要确定你的
结果是
IEnumerable
还是
IORDerenumerable
。但这很难说。如果你的意思是排序是在
ToList
之前完成的,那么我不想告诉你,但是你必须在添加添加
ThenBy
调用之前再次进行排序。@PatrickHoffman它给了我一个错误。我根据您的解决方案更新了问题。您仍然有反射来获取属性值。如何?它给了我“表达式树可能不包含动态操作”错误!然后改用
对象
并使用反射。所以您没有使用反射来获取属性。@patrickhofman它给了我一个错误。我更新了