Динамическая сортировка свойства навигации коллекции с помощью linq

К сожалению, значение таких вещей, как (и \ (меняются между регулярными выражениями стиля Emacs и большинством других стилей). Поэтому, если вы попытаетесь избежать этого, вы можете делать противоположное тому, что вы хотите.

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

1
задан Daniel A. White 18 March 2019 в 13:53
поделиться

2 ответа

Используйте EF.Property .

// Get the string name of the property here
string propertyName = "Title";
allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
    ? allRequests.OrderBy(x => EF.Property<string>(x, propertyName)).ToList()
    : allRequests.OrderByDescending(x => EF.Property<string>(x, propertyName)).ToList();

Что-то в этом роде может работать (не проверено, но компилируется)

// static for caching & performance 
static private MethodInfo efPropertyGenericMethod = typeof(EF).GetTypeInfo().GetDeclaredMethod("Property");

Expression SortBy<TEntity>(Type type, string propertyName)
{
    var xParam = Expression.Parameter(typeof(TEntity), "x");

    // set T generic type here for EF.Property<T>
    var efPropertyMethod = efPropertyGenericMethod.MakeGenericMethod(type);
    // Creates a Lambda
    Expression lambda = Expression.Lambda(
        // Calls a method. First parameter is null for static calls
        Expression.Call(null,
            efPropertyMethod, // our cosntructed generic Version of EF.Property<T>
            xParam, // Pass the x Parameter
            Expression.Constant(propertyName, typeof(string)) // the propertyName asconstant
        ),
        xParam
    );

    return lambda;
};

Для использования в качестве

allRequests.OrderBy(SortBy<TvRequests>(propertyType, propertyName))

Обратите внимание, что SortBy не называется в лямбде. Ниже будет неправильно (в строке выше нет x =>).

allRequests.OrderBy(x => SortBy<TvRequests>(propertyType, propertyName))

Что это делает? SortBy генерирует дерево выражений, эквивалентное x => EF.Property<T>(x, "MyPropertyName").

Редактировать:

Обновлен метод, поэтому x также передается в EF.Property(x, propertyName)

0
ответ дан Jamie Rees 18 March 2019 в 13:53
поделиться

Вы можете попробовать что-то вроде этого ..

public static class QueryableExtensions
{
    public enum SortDirection { ASC,DESC}
    static LambdaExpression CreateExpression(Type type, string propertyName)
    {
        var param = Expression.Parameter(type, "x");
        Expression body = param;
        body = propertyName.Split('.')
            .Select(prop => body = Expression.PropertyOrField(body, prop))
            .Last();
        return Expression.Lambda(body, param);
    }
    public static IQueryable<T> SortBy<T>(this IQueryable<T> source,string expressionField,SortDirection sortDirection = SortDirection.ASC)
    {
        var lambdaExpression = CreateExpression(typeof(T), expressionField) as dynamic;
        return sortDirection == SortDirection.ASC ? Queryable.OrderBy(source,lambdaExpression) : Queryable.OrderByDescending(source, lambdaExpression);
    }

}

типов

public class TvRequests
{
    public string Title { get; set; }
    public OmbiUser RequestedUser { get; set; }

    public DateTime Date { get; set; }
}

public class OmbiUser
{
    public string Username;
    public DateTime Date { get; set; }
}

с использованием

    List<TvRequests> reqList = new List<TvRequests>();
    reqList.Add(new TvRequests {
        Title = "A",
        Date = DateTime.Now.AddDays(-1),
        RequestedUser = new OmbiUser
        {
            Username = "A",
            Date = DateTime.Now.AddDays(-1)
        }
    });
    reqList.Add(new TvRequests
    {
        Title = "C",
        Date = DateTime.Now.AddDays(1),
        RequestedUser = new OmbiUser
        {
            Username = "C",
            Date = DateTime.Now.AddDays(1)
        }
    });
    reqList.Add(new TvRequests
    {
        Title = "B",
        Date = DateTime.Now,
        RequestedUser = new OmbiUser
        {
            Username = "B",
            Date = DateTime.Now
        }
    });
    foreach (var item in reqList.AsQueryable().SortBy("Date", SortDirection.DESC))
        Debug.WriteLine(item.Title);
    foreach (var item in reqList.AsQueryable().SortBy("RequestedUser.Date"))
        Debug.WriteLine(item.Title);
    foreach (var item in reqList.AsQueryable().SortBy("RequestedUser.UserName",SortDirection.DESC))
        Debug.WriteLine(item.Title);
0
ответ дан levent 18 March 2019 в 13:53
поделиться
Другие вопросы по тегам:

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