在Linq表达式中使用变量

时间:2013-04-10 18:50:58

标签: linq

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

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

按照非常常见的模式;网格可以'OrderBy'不同的列,具体取决于单击哪个列标题。我需要替换硬编码的'ProductName',以便可以包含任何可能的列名。 solution is probably based on the approach presented at this question but,但我的用例不同,我还没有能够实现任何东西。所以自动建议并没有提供任何其他明显看似奇怪的东西,因为这肯定是一个常见的问题。

我已经尝试过显而易见的事了:

var mySortColumn = "w.ProductId";

然后:

.OrderBy(w => mySortColumn)

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

This article suggests I should use a SWITCH/CASE construct为每个可能的'OrderBy'子句构建一个完全不同的查询。虽然我通常不会在黑客中出现问题但是; ICK。

看起来我们还没有进化到远离“构建字符串”的动态SQL日期。

1 个答案:

答案 0 :(得分: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