Можно ли взять свойство объекта в Linq из ввода строки? [Дубликат]

Для примера предположим, что у вас есть класс Person с помощью только name.

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Google GSON ( Maven )

Мой личный фаворит в отношении большой сериализации / де-сериализации объектов JSON.

Gson g = new Gson();

Person person = g.fromJson("{\"name\": \"John\"}", Person.class);
System.out.println(person.name); //John

System.out.println(g.toJson(person)); // {"name":"John"}

Обновить

Если вы хотите получить вы можете легко сделать это с помощью библиотеки Google:

JsonObject jsonObject = new JsonParser().parse("{\"name\": \"John\"}").getAsJsonObject();

System.out.println(jsonObject.get("name").getAsString()); //John

Org.JSON ( Maven )

Если вам не нужна де-сериализация объекта, а просто получить атрибут, вы можете попробовать org.json (или посмотреть пример GSON выше!) [/ ​​g13]

JSONObject obj = new JSONObject("{\"name\": \"John\"}");

System.out.println(obj.getString("name")); //John

Джексон ( Maven )

ObjectMapper mapper = new ObjectMapper();
Person user = mapper.readValue("{\"name\": \"John\"}", Person.class);

System.out.println(user.name); //John

46
задан Stijn 5 March 2014 в 12:12
поделиться

8 ответов

Абсолютно. Вы можете использовать LINQ Dynamic Query Library, найденную в блоге Скотта Гатри . Также доступна обновленная версия для CodePlex .

Позволяет создавать предложения OrderBy, Where и почти все остальное, передавая строковые параметры. Он отлично работает для создания общего кода для сортировки / фильтрации сетки и т. Д.

var result = data
    .Where(/* ... */)
    .Select(/* ... */)
    .OrderBy("Foo asc");

var query = DbContext.Data
    .Where(/* ... */)
    .Select(/* ... */)
    .OrderBy("Foo ascending");
38
ответ дан Mike Mooney 26 August 2018 в 11:14
поделиться

Для этого вам не нужна внешняя библиотека. Следующий код работает для LINQ to SQL / entity.

    /// <summary>
    /// Sorts the elements of a sequence according to a key and the sort order.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of <paramref name="query" />.</typeparam>
    /// <param name="query">A sequence of values to order.</param>
    /// <param name="key">Name of the property of <see cref="TSource"/> by which to sort the elements.</param>
    /// <param name="ascending">True for ascending order, false for descending order.</param>
    /// <returns>An <see cref="T:System.Linq.IOrderedQueryable`1" /> whose elements are sorted according to a key and sort order.</returns>
    public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> query, string key, bool ascending = true)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            return query;
        }

        var lambda = (dynamic)CreateExpression(typeof(TSource), key);

        return ascending 
            ? Queryable.OrderBy(query, lambda) 
            : Queryable.OrderByDescending(query, lambda);
    }

    private static LambdaExpression CreateExpression(Type type, string propertyName)
    {
        var param = Expression.Parameter(type, "x");

        Expression body = param;
        foreach (var member in propertyName.Split('.'))
        {
            body = Expression.PropertyOrField(body, member);
        }

        return Expression.Lambda(body, param);
    }

(CreateExpression скопирован из https://stackoverflow.com/a/16208620/111438 )

27
ответ дан Community 26 August 2018 в 11:14
поделиться

В одном ответе выше:

Простейший & amp; лучшее решение:

mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s));

Существует синтаксическая ошибка, необходимо добавить ,null:

mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s,null));
-2
ответ дан Eiko 26 August 2018 в 11:14
поделиться

Я сделал так:

using System.Linq.Expressions;

namespace System.Linq
{
    public static class LinqExtensions
    {

        public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string field, string dir = "asc")
        {
            // parametro => expressão
            var parametro = Expression.Parameter(typeof(TSource), "r");
            var expressao = Expression.Property(parametro, field);
            var lambda = Expression.Lambda<Func<TSource, string>>(expressao, parametro); // r => r.AlgumaCoisa
            if (string.Equals(dir, "desc", StringComparison.InvariantCultureIgnoreCase)){
                return source.OrderByDescending(lambda);
            }
            return source.OrderBy(lambda);
        }

        public static IOrderedQueryable<TSource> ThenBy<TSource>(this IOrderedQueryable<TSource> source, string field, string dir = "asc")
        {
            var parametro = Expression.Parameter(typeof(TSource), "r");
            var expressao = Expression.Property(parametro, field);
            var lambda = Expression.Lambda<Func<TSource, string>>(expressao, parametro); // r => r.AlgumaCoisa
            if (string.Equals(dir, "desc", StringComparison.InvariantCultureIgnoreCase))
            {
                return source.ThenByDescending(lambda);
            }
            return source.ThenBy(lambda);
        }

    }
}

Использование:

example.OrderBy("Nome", "desc").ThenBy("other")

Работает как:

example.OrderByDescending(r => r.Nome).ThenBy(r => r.other)
2
ответ дан Gustavo Rossi Muller 26 August 2018 в 11:14
поделиться

Простейший & amp; лучшее решение:

mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s));
8
ответ дан Kasper Roma 26 August 2018 в 11:14
поделиться

Если вы используете простые LINQ-to-objects и не хотите зависеть от внешней библиотеки, нетрудно добиться того, чего вы хотите.

Предложение OrderBy() принимает Func<TSource, TKey>, который получает ключ сортировки из исходного элемента. Вы можете определить функцию вне предложения OrderBy():

Func<Item, Object> orderByFunc = null;

Затем вы можете назначить ее различным значениям в зависимости от критериев сортировки:

if (sortOrder == SortOrder.SortByName)
  orderByFunc = item => item.Name;
else if (sortOrder == SortOrder.SortByRank)
  orderByFunc = item => item.Rank;

Затем вы можете сортировать :

var sortedItems = items.OrderBy(orderByFunc);

В этом примере предполагается, что тип источника Item имеет свойства Name и Rank.

Обратите внимание, что в этом примере TKey есть Object, чтобы не ограничивать типы свойств, которые можно сортировать. Если func возвращает тип значения (например, Int32), он будет загружаться при сортировке, а это несколько неэффективно. Если вы можете ограничить TKey определенным типом значения, вы можете обойти эту проблему.

58
ответ дан Martin Liversage 26 August 2018 в 11:14
поделиться

Вам нужно использовать библиотеку запросов LINQ Dynamic для передачи параметров во время выполнения,

Это позволит использовать выражения linq, такие как

string orderedBy = "Description";
var query = (from p in products
            orderby(orderedBy)
            select p);
5
ответ дан Nicholas Murray 26 August 2018 в 11:14
поделиться

Посмотрите на этот блог здесь . Он описывает способ сделать это, определяя EntitySorter<T>.

Он позволяет вам передать IEntitySorter<T> в ваши методы обслуживания и использовать его следующим образом:

public static Person[] GetAllPersons(IEntitySorter<Person> sorter)
{
    using (var db = ContextFactory.CreateContext())
    {
        IOrderedQueryable<Person> sortedList = sorter.Sort(db.Persons);

        return sortedList.ToArray();
    }
}

И вы можете создать EntitiySorter следующим образом:

IEntitySorter<Person> sorter = EntitySorter<Person>
    .OrderBy(p => p.Name)
    .ThenByDescending(p => p.Id);

Или вот так:

var sorter = EntitySorter<Person>
     .OrderByDescending("Address.City")
     .ThenBy("Id");
7
ответ дан Steven 26 August 2018 в 11:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: