带有字符串 keySelector 的 OrderBy

发布于 2024-10-11 21:24:07 字数 1404 浏览 1 评论 0原文

我有以下函数,它根据对象的属性提取不同的值,这里是 Client.

    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 按预期工作吗?

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

预先非常感谢, 约翰.

I have the following function that is extracting me distinct values based on the properties of an object, here Client.

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

I'm doing this because I do not know in before which property values I'll need to extract.
It's working, just the result is not sorted.

Can you please help me correct the sorting to make the OrderBy work as expected?

The properties are strings and I don't need to chain the sorting. I don't need to specify the sorting order either.

Thanks a lot in advance,
John.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

離殇 2024-10-18 21:24:07

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

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

按项目本身进行排序

Your keySelector currently returns the same string for each (the property name); and since LINQ is typically a stable sort, this results in no overall change. Since you have already projected to the string values, you can simply use a trivial x=>x mapping here:

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

to order by the items themselves.

撩心不撩汉 2024-10-18 21:24:07

感谢您提供优雅的解决方案。我进一步扩展了 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"));

Thanks for the elegant solution. I further expanded upon the CreateSelectorExpression method so it can be leveraged outside of the Client class in the example above.

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

Usage

Func<IQueryable<YourEntity>, IOrderedQueryable<YourEntity>> orderBy = o => o.OrderByDescending(CreateSelectorExpression<YourEntity>("Entity Property Name"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文