C#linq - 在运行时更改选定的字段

时间:2012-01-23 10:00:18

标签: c# linq dynamic expression-trees

我有一个对象订单(订单,产品,成本,价格,客户,日)。 我正在从数据库中检索大量记录并为了便于过滤,我需要使用检索到的不同值来丢弃DropDownLists,这样用户只能选择特定日期或特定产品甚至特定价格。 DropDownList的ID创建为“ddl_”+相关字段的名称。

我想要的是能够像这样定义一个简单的数组:

public string[] filterArray = new string[] { "Order", "Product", "Cost", "Price", "Client", "Day" };

然后调用BindDLLs方法:

foreach (string filterName in filterArray)
{
    // Find the ddl to populate
    DropDownList ddl = (DropDownList)this.FindControl("ddl_" + filterName);
    // Get the data for that ddl only (use filterName in the select...)
    var query = (from items in results select items.filterName.ToString()).Distinct();

    // Populate the ddl (not complete code...)
    foreach (var item in query)
    {
        ddl.Items.Add(item...);
    }
}

我的问题是我找到了很多关于如何在运行时修改WHERE或GROUP BY或linq语句的任何其他部分的文档。我只是没有发现如何动态更改我想要检索的字段。

有一种简单的方法吗?谢谢。 蛇皮

编辑:

List<Orders> results = OrdersService.GetOrders();

public class Orders
{
    [DataMember]
    public DateTime? Day
    [DataMember]
    public int? Order
    [DataMember]
    public int? Product
    [DataMember]
    public int? Cost
    [DataMember]
    public int? Price
    [DataMember]
    public int? Client
    [DataMember]
}

2 个答案:

答案 0 :(得分:2)

您可以通过手动构建lambda表达式来解决此问题。

您当前使用的查询可以更改为使用方法链语法,然后如下所示:

var query = results.Select(item => item.<filterName>.ToString()).Distinct();

现在我们需要创建自己传递给Distinct的lambda表达式。

这可以使用以下方法实现:

Expression<Func<YourResultType, string>> CreateExpression(string propertyName)
{
    var itemExpression = Expression.Parameter(typeof(YourResultType), "item");
    var propertyExpression = Expression.Property(itemExpression, propertyName);
    var toStringExpression = Expression.Call(propertyExpression,
                                             "ToString", null);
    return Expression.Lambda<Func<YourResultType, string>>(toStringExpression, 
                                                           itemExpression);
}

现在我们可以将查询更改为:

var query = results.Select(CreateExpression(filterName)).Distinct();

请注意,您需要将YourResultType更改为results变量中的实例类型。此外,如果您不是查询数据库而是查询内存列表,则需要将查询更改为:

var query = results.Select(CreateExpression(filterName).Compile()).Distinct();

答案 1 :(得分:0)