【问题标题】:Use a variable in a Linq expression在 Linq 表达式中使用变量
【发布时间】:2013-04-10 18:50:57
【问题描述】:

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

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

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

我已经尝试了显而易见的方法:

var mySortColumn = "w.ProductId";

然后:

.OrderBy(w => mySortColumn)

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

This article suggests I should use a SWITCH/CASE construct 为我的每个可能的“OrderBy”子句构建一个完全不同的查询。虽然我通常不会对黑客行为嗤之以鼻,但是;艾克。

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

【问题讨论】:

  • 您可以为每一列存储 w => w.ProductName 之类的表达式,然后在查询 OrderBy(productColumnExpression) 中替换它们。

标签: linq


【解决方案1】:

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;
    }
}

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

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多