C # Превращение магической строки в лямбда-выражение
У меня есть набор методов расширения, которые позволяют использовать магические строки в LINQOrderBy()
методы. Я знаю, первый вопрос будет, почему, но этоЯвляется частью универсального репозитория и обеспечивает гибкость, позволяющую отправлять строки из пользовательского интерфейса и использовать их напрямую.
У меня это работает, если вы передаете волшебную строку, которая представляет свойство основной сущности, к которой вы обращаетесь, но яУ меня возникли проблемы с тем, чтобы сделать его более общим, чтобы он мог обрабатывать несколько уровней глубокой магической струны. Например:
IQueryable contacts = GetContacts();
contacts.OrderByProperty("Name"); // works great
// can't figure out how to handle this
contacts.OrderByProperty("ContactType.Name");
Вот код, который у меня есть до сих пор:
public static class LinqHelpers
{
private static readonly MethodInfo OrderByMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderBy" && method.GetParameters().Length == 2);
private static readonly MethodInfo OrderByDescendingMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderByDescending" && method.GetParameters().Length == 2);
private static readonly MethodInfo ThenByMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "ThenBy" && method.GetParameters().Length == 2);
private static readonly MethodInfo ThenByDescendingMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "ThenByDescending" && method.GetParameters().Length == 2);
public static IOrderedQueryable ApplyOrdering(IQueryable source, string propertyName, MethodInfo orderingMethod)
{
var parameter = Expression.Parameter(typeof(TSource), "x");
var orderByProperty = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda(orderByProperty, new[] { parameter });
var genericMethod = orderingMethod.MakeGenericMethod(new[] { typeof(TSource), orderByProperty.Type });
return (IOrderedQueryable)genericMethod.Invoke(null, new object[] { source, lambda });
}
public static IOrderedQueryable OrderByProperty(this IQueryable source, string propertyName)
{
return ApplyOrdering(source, propertyName, OrderByMethod);
}
public static IOrderedQueryable OrderByDescendingProperty(this IQueryable source, string propertyName)
{
return ApplyOrdering(source, propertyName, OrderByDescendingMethod);
}
public static IOrderedQueryable ThenByProperty(this IOrderedQueryable source, string propertyName)
{
return ApplyOrdering(source, propertyName, ThenByMethod);
}
public static IOrderedQueryable ThenByDescendingProperty(this IOrderedQueryable source, string propertyName)
{
return ApplyOrdering(source, propertyName, ThenByDescendingMethod);
}
}
Я уверен, что мне нужно разделитьpropertyName
на период, а затем использовать эти части, чтобы создать более сложное выражение, которое включает в себяMemberExpression
а затем собственность, но яЯ изо всех сил. Любая помощь или указание в правильном направлении будет принята с благодарностью.