5 Stimmen

OrderBy mit einem String keySelector

Ich habe die folgende Funktion, die mich verschiedene Werte auf der Grundlage der Eigenschaften eines Objekts, hier Client extrahiert.

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

Ich tue dies, weil ich vorher nicht weiß, welche Eigenschaftswerte ich extrahieren muss. Es funktioniert, nur das Ergebnis ist nicht sortiert.

Können Sie mir bitte helfen, die Sortierung zu korrigieren, damit das OrderBy wie erwartet funktioniert?

Die Eigenschaften sind Zeichenketten, und ich muss die Sortierung nicht verketten. Ich muss auch die Sortierreihenfolge nicht angeben.

Vielen Dank im Voraus, John.

7voto

Marc Gravell Punkte 970173

あなたの keySelector gibt derzeit zurück derselbe String für jede (den Eigenschaftsnamen); und da LINQ in der Regel eine stabile Sortierung ist, führt dies zu keiner Gesamtänderung. Da Sie bereits auf die String-Werte projiziert haben, können Sie einfach ein triviales x=>x hier kartieren:

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

auf Bestellung durch die Gegenstände selbst .

6voto

Vielen Dank für diese elegante Lösung. Ich habe die CreateSelectorExpression-Methode weiter ausgebaut, damit sie auch außerhalb der Client-Klasse im obigen Beispiel genutzt werden kann.

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

Verwendung

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X