속성 이름을 문자열로 사용하여 정렬

asp.net asp.net-core c# entity-framework-core linq

문제

내 웹 API가 다음과 같은 문자열 매개 변수로 출력을 정렬 할 수있게하고 싶습니다.

http://myapi.com/api/people?skip=0&take=50&orderBy=lastName&descending=true .

내 API에서도 페이지 매김 지원 ( skiptake )을 지원하므로 orderBydescending 매개 변수를 SQL 쿼리에 직접 적용하여 올바른 결과가 데이터베이스에서 제공되도록하고 싶습니다.

그러나이 작업을 수행 할 때 orderBy 의 매개 변수를 문자열 비교를 사용하여 정렬하려는 클래스의 실제 속성과 일치 시키려고하면 코드를 관리하기가 매우 어려워 질 수 있습니다.

나는 새로운 Core CLR을 사용하여이 코드를 컴파일하려고 할 때 LINQ to Entities와 새로운 EF7과 함께 작동하도록되어있는 해결책 을 찾았지만 다음 메시지를 얻습니다.

오류 CS1503 인수 2 : 'System.Linq.Expressions.Expression>'에서 'string'으로 변환 할 수 없습니다.

실패한 솔루션의 코드는 OrderBy<T> 메서드입니다.

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
    return source.OrderBy(ToLambda<T>(propertyName));
}

새로운 Core CLR이이 시도를 지원하지 않는 것 같습니다. 솔루션을 새 CLR로 사용할 수있는 또 다른 방법이 있습니까? 그렇지 않다면 EF7을 사용하여 정렬 할 수있는 또 다른 대안이 무엇입니까? if 또는 switch 문을 사용하여 입력 문자열을 속성 이름과 비교하지 않아도됩니까?

수락 된 답변

링크의 솔루션은 LINQ to Entities에서 대부분 작동하지 않는 "Expression.Convert"를 사용합니다.

다음은 작동하는 확장 메소드입니다.

public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
    // LAMBDA: x => x.[PropertyName]
    var parameter = Expression.Parameter(typeof(TSource), "x");
    Expression property = Expression.Property(parameter, propertyName);
    var lambda = Expression.Lambda(property, parameter);

    // REFLECTION: source.OrderBy(x => x.Property)
    var orderByMethod = typeof(Queryable).GetMethods().First(x => x.Name == "OrderBy" && x.GetParameters().Length == 2);
    var orderByGeneric = orderByMethod.MakeGenericMethod(typeof(TSource), property.Type);
    var result = orderByGeneric.Invoke(null, new object[] { source, lambda });

    return (IOrderedQueryable<TSource>)result;
}

면책 조항 : 저는 GitHub의 EF + 프로젝트 소유자입니다.

내 저장소에서 속성 이름별로 정렬 할 다른 방법을 찾을 수 있습니다 : GitHub

  • OrderByDescending
  • 그 다음에
  • 그렇다면
  • AddOrAppendOrderBy
  • AddOrAppendOrderByDescending

편집 : 답변을 하위 질문

이 같은 것을 사용하여 탐색 속성별로 정렬 할 수 있습니까? 예 : 속성 이름 "NavigationProperty.PropertyName"

예, 문자열과 루프를 분할하여 속성 경로를 사용하여 표현식을 만들거나 실제 표현식 평가기를 사용할 수 있습니다.

면책 조항 : 저는 Eval-Expressions.NET 프로젝트의 소유자입니다.

이 라이브러리를 사용하면 모든 LINQ 메소드를 동적으로 실행할 수 있습니다.

참고 : LINQ Dynamic

public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
    // LAMBDA: x => x.[PropertyName]
    var parameter = Expression.Parameter(typeof(TSource), "x");
    Expression property = Expression.Property(parameter, propertyName);
    var lambda = Expression.Lambda(property, parameter);

    // REFLECTION: source.OrderBy(x => x.Property)
    var orderByMethod = typeof(Queryable).GetMethods().First(x => x.Name == "OrderBy" && x.GetParameters().Length == 2);
    var orderByGeneric = orderByMethod.MakeGenericMethod(typeof(TSource), property.Type);
    var result = orderByGeneric.Invoke(null, new object[] { source, lambda });

    return (IOrderedQueryable<TSource>)result;
}



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.