0

我正在编写一个 Linq 查询,其中我的对象在我的视图中构建了一个网格(表)。

filteredProducts =
    filteredProducts.Take(take)
                    .Skip(pagesToSkip)
                    .OrderBy(w => w.ProductName)
                    .ToList();

按照非常常见的模式;根据单击的列标题,网格可以“排序”不同的列。我需要替换硬编码的“ProductName”,以便可以包含任何可能的列名。该解决方案可能基于this question提出的方法,但我的用例足够不同,以至于我还无法实现任何东西。SO的自动建议没有提供任何其他看起来很奇怪的明显问题,因为这肯定是一个常见问题。

我已经尝试了明显的:

var mySortColumn = "w.ProductId";

然后:

.OrderBy(w => mySortColumn)

并且不会收到编译或运行时投诉,但也不尊重指定值。我尝试过的其他变体会立即抛出编译器错误。

本文建议我应该使用 SWITCH/CASE 构造来为每个可能的“OrderBy”子句构建一个完全不同的查询。虽然我通常不会对黑客行为嗤之以鼻,但是;伊克。

看起来我们离动态 SQL 时代的“构建字符串”时代还没有那么远。

4

1 回答 1

0

OrderBy方法需要一个Func<Type,int>委托。这意味着您可以执行以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
class Program
{

    static void Main(string[] args)
    {
        var foos = new List<Foo>()
        {
            new Foo { A = 1, B = 2 },
            new Foo { A = 2, B = 1 }
        };

        Func<Foo, int> a = f => f.A;
        Func<Foo, int> b = f => f.B;

        bool orderByA = false;

        Display(foos.OrderBy(orderByA ? a : b));
    }

    private static void Display(IEnumerable<Foo> foos)
    {
        foos.ToList().ForEach(f => Console.WriteLine(f));
    }
}

class Foo
{
    public int A { get; set; }
    public int B { get; set; }

    public override string ToString()
    {
        return A + " " + B;
    }
}

如果您真的希望能够对属性名称进行排序,则需要创建一些代码来Expression从您的string.

于 2013-04-10T18:59:26.957 回答