【问题标题】:OrderBy with a String keySelectorOrderBy 带字符串 keySelector
【发布时间】:2011-01-11 13:30:55
【问题描述】:

我有以下函数,它根据对象的属性提取不同的值,这里是客户端。

    public List<DistinctValue> GetDistinctValues(string propertyName)
    {
        //how should I specify the keySelector ?
        Func<string, object> keySelector = item => propertyName;

        var list = new List<DistinctValue>();
        var values = this.ObjectContext.Clients.Select(CreateSelectorExpression
                              (propertyName)).Distinct().OrderBy(keySelector);
        int i = 0;
        foreach (var value in values)
        {
            list.Add(new DistinctValue() { ID = i, Value = value });
            i++;
        }

        return list;
    }

    private static Expression<Func<Client, string>> CreateSelectorExpression
                                                        (string propertyName)
    {
        var paramterExpression = Expression.Parameter(typeof(Client));
        return (Expression<Func<Client, string>>)Expression.Lambda(
             Expression.PropertyOrField(paramterExpression, propertyName), 
                                                   paramterExpression);
    }

public class DistinctValue
{
    [Key]
    public int ID { get; set; }
    public string Value { get; set; }
}

我这样做是因为我不知道之前需要提取哪些属性值。 它正在工作,只是结果没有排序。

您能帮我更正排序以使 OrderBy 按预期工作吗?

属性是字符串,我不需要链接排序。我也不需要指定排序顺序。

提前非常感谢, 约翰。

【问题讨论】:

    标签: c# .net linq lambda


    【解决方案1】:

    您的keySelector 当前为每个(属性名称)返回相同的字符串;并且由于 LINQ 通常是一种稳定的排序,因此不会导致整体变化。由于您已经投影到字符串值,您可以在这里简单地使用一个简单的x=&gt;x 映射:

    var values = this.ObjectContext.Clients.Select(
        CreateSelectorExpression(propertyName)).Distinct().OrderBy(x => x);
    

    按项目本身订购

    【讨论】:

    • 感谢您的回答和解释。这很有道理。再次感谢。
    【解决方案2】:

    感谢您提供优雅的解决方案。我进一步扩展了 CreateSelectorExpression 方法,以便可以在上面示例中的 Client 类之外使用它。

    public static Expression<Func<T, string>> CreateSelectorExpression<T>(string propertyName)
    {
        var paramterExpression = Expression.Parameter(typeof(T));
            return (Expression<Func<T, string>>)Expression.Lambda(Expression.PropertyOrField(paramterExpression, propertyName),
                                                                    paramterExpression);
    }     
    

    用法

    Func<IQueryable<YourEntity>, IOrderedQueryable<YourEntity>> orderBy = o => o.OrderByDescending(CreateSelectorExpression<YourEntity>("Entity Property Name"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      • 2017-03-25
      相关资源
      最近更新 更多