Создайте лямбда-выражение из пути к собственности - PullRequest
1 голос
/ 02 ноября 2010

Привет, допустим, у меня есть путь свойства, похожий на этот

Можно сказать, что у меня есть статья, в которой есть НДС, а НДС имеет Значение.Теперь я хочу использовать Linq для сортировки списка, используя этот путь свойства. Как я могу построить это лямбда-выражение, когда у меня есть «Vat.Value» в строке, и мне нужен следующий результат

list.Order(x => x.Vat.Value)

всегда знаю типы Vat и Value, иногда это только x.Name, для которого я отсутствую.

Ответы [ 3 ]

2 голосов
/ 02 ноября 2010

Я исправил это методом расширения.Подход к использованию пути свойства теперь, например,

var orderedArticles = articles.OrderBy("Vat.Value");

вместо

var orderedArticles = articles.OrderBy(x => x.Vat.Value)

Методы расширения:

private static Func<T, TReturnType> GetLambda<T, TReturnType>(IEnumerable<string> propertyNames)
{
    var rootParameterExression = Expression.Parameter(typeof(T));

    Expression expression = rootParameterExression;
    foreach (var propertyName in propertyNames)
    {
        expression = Expression.Property(expression, propertyName);
    }
    return Expression.Lambda<Func<T, TReturnType>>(expression, rootParameterExression).Compile();
}

public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> queryable, string propertyPath)
{
    var propertyPathList = propertyPath.Split(Convert.ToChar("."));
    Type propertyType = typeof(T);
    foreach (var propertyName in propertyPathList)
    {
        propertyType = propertyType.GetProperty(propertyName).PropertyType;
    }

    if(propertyType == typeof(decimal))
    {
        var lambda = GetLambda<T, Decimal>(propertyPathList);
        return queryable.OrderBy(lambda);
    }
    var lamda = GetLambda<T, object>(propertyPathList);
    return queryable.OrderBy(lamda);
}
1 голос
/ 02 ноября 2010

Есть ли причина, по которой вы не можете использовать существующую библиотеку LINQ Dynamic Query, которая имеет перегрузки, которые принимают строки?

http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Возможно, он делает то же, что вы только что написали, но его код, который вам не нужно поддерживать, и может иметь некоторые оптимизации.

0 голосов
/ 02 ноября 2010

Я не уверен, что полностью понимаю вопрос, но что-то вроде этого выглядит так, как вы хотите.Обратите внимание, что я бы, вероятно, реорганизовал лямбду в вспомогательный метод в производстве для ясности.Также обратите внимание, что подобное отражение может значительно повлиять на производительность в зависимости от размера вашей коллекции.

[Test]
public void OrderByUsingReflection()
{
    var values = new[] 
    {
        new { Vat = new { Value = "two"}},
        new { Vat = new {Value = "one"}},
    };

    var result = values.OrderBy(x =>
    {
        var vat = x.GetType().GetProperty("Vat").GetValue(x, null);
        return vat.GetType().GetProperty("Value").GetValue(vat, null);
    });

    Assert.AreEqual(result.ToList()[0], values[1]);
    Assert.AreEqual(result.ToList()[1], values[0]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...