Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 延伸Marc Gravell';s动态Linq OrderBy_C#_Linq_Dynamic_Sql Order By_Linq To Objects - Fatal编程技术网

C# 延伸Marc Gravell';s动态Linq OrderBy

C# 延伸Marc Gravell';s动态Linq OrderBy,c#,linq,dynamic,sql-order-by,linq-to-objects,C#,Linq,Dynamic,Sql Order By,Linq To Objects,我发现Marc Gravell的动态顺序非常棒: 我把它放在一个类中,LinqHelper。在这个类中,我还创建了两个新类,以便在我的代码中可以做到这一点: var q = db.tblJobHeaders; LinqHelper.OrderByCollection OBys = new LinqHelper.OrderByCollection(); OBys.AddOrderBy("some field", true); OBys.AddOrderBy("anotherfield", fa

我发现Marc Gravell的动态顺序非常棒:

我把它放在一个类中,
LinqHelper
。在这个类中,我还创建了两个新类,以便在我的代码中可以做到这一点:

var q = db.tblJobHeaders;

LinqHelper.OrderByCollection OBys = new LinqHelper.OrderByCollection();
OBys.AddOrderBy("some field", true);
OBys.AddOrderBy("anotherfield", false);
OBys.ExecuteOrderBys(q);
实现这一目标的类别有:

/// <summary>
/// A collection of order bys
/// </summary>
public class OrderByCollection
{
    private ArrayList Orderings = new ArrayList();

    public OrderByCollection(){ }

    /// <summary>
    /// Add an order by to this collection
    /// </summary>
    public void AddOrderBy(string Field, bool Descending)
    {
        OrderByObj NewObj = new OrderByObj(Descending, Field);
        this.Orderings.Add(NewObj);
    }

    /// <summary>
    /// Executes the order bys
    /// </summary>
    public IOrderedQueryable<T> ExecuteOrderBys<T>(this IOrderedQueryable<T> source)
    {
        int ExecutionIndex = 0;
        foreach (OrderByObj O in this.Orderings)
        {
            if (ExecutionIndex == 0)
            {
                if (O.Descending)
                    source = LinqHelper.OrderByDescending(source, O.Field);
                else
                    source = LinqHelper.OrderBy(source, O.Field);
            }
            else
            {
                if (O.Descending)
                    source = LinqHelper.ThenByDescending(source, O.Field);
                else
                    source = LinqHelper.ThenBy(source, O.Field);
            }
            ExecutionIndex++;
        }
        return (IOrderedQueryable<T>)source;
    }
}

/// <summary>
/// An order by object
/// </summary>
private class OrderByObj
{
    public bool Descending { get; set; }
    public string Field { get; set; }

    public OrderByObj(bool IsDescending, string DatabaseField)
    {
        this.Descending = IsDescending;
        this.Field = DatabaseField;
    }
}
这就产生了错误:

方法的类型参数 'LinqHelper.OrderByCollection.ExecuteOrderBys(System.Linq.IOrderedQueryable)' 无法从用法推断。尝试 指定类型参数 明确地说


如果有人能帮忙的话,我对此有点困惑,我是否正确地传入
var q
,然后正确地返回它?

我打赌
q
的类型是
IQueryable
而不是
IOrderedQueryable
。只需更改签名就可以了,因为您从
OrderBy
开始

然后,您将需要一个
IOrderedQueryable
用于
ThenBy
s。您可以直接强制转换它,因为您可以肯定地知道,从上一次调用到
OrderBy
ThenBy
都有一个
IOrderedQueryable

如果你不喜欢演员阵容,你需要做一些改变:

public IOrderedQueryable<T> ExecuteOrderBys<T>(this IQueryable<T> source)
{
    if(!this.Orderings.Any())
        throw new InvalidOperationException("You need to add orderings");
    IOrderedQueryable<T> ordered;
    if (this.Orderings[0].Descending)
        ordered = LinqHelper.OrderByDescending(source, this.Orderings[0].Field);
    else
        ordered = LinqHelper.OrderBy(source, this.Orderings[0].Field);
    foreach(var ordering in this.Orderings.Skip(1))
    {
        if (ordering.Descending)
            ordered = LinqHelper.ThenByDescending(source, ordering.Field);
        else
            ordered = LinqHelper.ThenBy(source, ordering.Field);
    }
    return ordered;
}
public IOrderedQueryable ExecuteOrderBys(此IQueryable源代码)
{
如果(!this.Orderings.Any())
抛出新的InvalidOperationException(“您需要添加订单”);
IOrderedQueryable-ordered;
if(this.Orderings[0]。降序)
ordered=LinqHelper.OrderByDescending(源,this.Orderings[0]。字段);
其他的
ordered=LinqHelper.OrderBy(源,this.Orderings[0]。字段);
foreach(本.Orderings.Skip(1)中的变量排序)
{
if(排序、降序)
ordered=LinqHelper.ThenByDescending(源,ordering.Field);
其他的
ordered=LinqHelper.ThenBy(source,ordering.Field);
}
订购退货;
}

请注意,如果不添加任何排序,代码将非常失败,因为最后转换为
IOrderedQueryable
。您可以将返回类型更改为
IQueryable
(以后将失去“附加”更多OrderBy的功能),或者在没有OrderBy的情况下抛出,就像我所做的那样。

谢谢,这似乎可行,但会在
ExecuteOrderBys
中的'ThenBy'语句上抛出错误:
方法'LinqHelper.ThenBy'的类型参数(System.Linq.IOrderedQueryable,字符串)'无法从用法中推断。请尝试显式指定类型参数。
Super这似乎很有效!我会检查一切是否正常谢谢您的帮助!@Tom:旁注:请不要使用
ArrayList
。将
ArrayList
视为过时。使用
List
,或者在您的情况下使用
List
,w这应该可以。很抱歉最后的评论。我的意思是
列表
。谢谢Martin,只是一个简单的问题,所有这些order BY延迟执行是否像常规linq查询一样?(我想是的,只是检查一下)
public IOrderedQueryable<T> ExecuteOrderBys<T>(this IQueryable<T> source)
{
    if(!this.Orderings.Any())
        throw new InvalidOperationException("You need to add orderings");
    IOrderedQueryable<T> ordered;
    if (this.Orderings[0].Descending)
        ordered = LinqHelper.OrderByDescending(source, this.Orderings[0].Field);
    else
        ordered = LinqHelper.OrderBy(source, this.Orderings[0].Field);
    foreach(var ordering in this.Orderings.Skip(1))
    {
        if (ordering.Descending)
            ordered = LinqHelper.ThenByDescending(source, ordering.Field);
        else
            ordered = LinqHelper.ThenBy(source, ordering.Field);
    }
    return ordered;
}