如何指定传递给orderby
使用我作为参数的值的参数?
例如:
List<Student> existingStudends = new List<Student>{ new Student {...}, new Student {...}}
Run Code Online (Sandbox Code Playgroud)
目前实施:
List<Student> orderbyAddress = existingStudends.OrderBy(c => c.Address).ToList();
Run Code Online (Sandbox Code Playgroud)
而不是c.Address
,我如何将其作为参数?
例
string param = "City";
List<Student> orderbyAddress = existingStudends.OrderByDescending(c => param).ToList();
Run Code Online (Sandbox Code Playgroud)
cod*_*ion 119
这是使用反射的可能性......
var param = "Address";
var propertyInfo = typeof(Student).GetProperty(param);
var orderByAddress = items.OrderBy(x => propertyInfo.GetValue(x, null));
Run Code Online (Sandbox Code Playgroud)
Ica*_*rus 111
您可以使用一点反射来构造表达式树,如下所示(这是一个扩展方法):
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty,
bool desc)
{
string command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExpression));
return source.Provider.CreateQuery<TEntity>(resultExpression);
}
Run Code Online (Sandbox Code Playgroud)
orderByProperty
是您要订购的属性名称,如果传递为true作为参数desc
,将按降序排序; 否则,将按升序排序.
现在你应该可以做existingStudents.OrderBy("City",true);
或existingStudents.OrderBy("City",false);
小智 7
2)添加以下代码
public static class OrderUtils
{
public static string ToStringForOrdering<T, TKey>(this Expression<Func<T, TKey>> expression, bool isDesc = false)
{
var str = expression.Body.ToString();
var param = expression.Parameters.First().Name;
str = str.Replace("Convert(", "(").Replace(param + ".", "");
return str + (isDesc ? " descending" : "");
}
}
Run Code Online (Sandbox Code Playgroud)
3)写下您的开关以选择Lambda函数
public static class SortHelper
{
public static Expression<Func<UserApp, object>> UserApp(string orderProperty)
{
orderProperty = orderProperty?.ToLowerInvariant();
switch (orderProperty)
{
case "firstname":
return x => x.PersonalInfo.FirstName;
case "lastname":
return x => x.PersonalInfo.LastName;
case "fullname":
return x => x.PersonalInfo.FirstName + x.PersonalInfo.LastName;
case "email":
return x => x.Email;
}
}
}
Run Code Online (Sandbox Code Playgroud)
4)使用你的助手
Dbset.OrderBy(SortHelper.UserApp("firstname").ToStringForOrdering())
Run Code Online (Sandbox Code Playgroud)
5)你可以使用pagging(PagedList)
public virtual IPagedList<T> GetPage<TOrder>(Page page, Expression<Func<T, bool>> where, Expression<Func<T, TOrder>> order, bool isDesc = false,
params Expression<Func<T, object>>[] includes)
{
var orderedQueryable = Dbset.OrderBy(order.ToStringForOrdering(isDesc));
var query = orderedQueryable.Where(where).GetPage(page);
query = AppendIncludes(query, includes);
var results = query.ToList();
var total = Dbset.Count(where);
return new StaticPagedList<T>(results, page.PageNumber, page.PageSize, total);
}
Run Code Online (Sandbox Code Playgroud)
说明
System.Linq.Dynamic允许我们在OrderBy方法中设置字符串值.但是在这个扩展中,字符串将被解析为Lambda.所以我认为如果我们将Lambda解析为字符串并将其提供给OrderBy方法将会有效.它的工作原理!
private Func<T, object> GetOrderByExpression<T>(string sortColumn)
{
Func<T, object> orderByExpr = null;
if (!String.IsNullOrEmpty(sortColumn))
{
Type sponsorResultType = typeof(T);
if (sponsorResultType.GetProperties().Any(prop => prop.Name == sortColumn))
{
System.Reflection.PropertyInfo pinfo = sponsorResultType.GetProperty(sortColumn);
orderByExpr = (data => pinfo.GetValue(data, null));
}
}
return orderByExpr;
}
public List<T> OrderByDir<T>(IEnumerable<T> source, string dir, Func<T, object> OrderByColumn)
{
return dir.ToUpper() == "ASC" ? source.OrderBy(OrderByColumn).ToList() : source.OrderByDescending(OrderByColumn).ToList();``
}
// Call the code like below
var orderByExpression= GetOrderByExpression<SearchResultsType>(sort);
var data = OrderByDir<SponsorSearchResults>(resultRecords, SortDirectionString, orderByExpression);
Run Code Online (Sandbox Code Playgroud)
要通过@Icarus扩展答案:如果您希望扩展方法的返回类型为IOrderedQueryable而不是IQueryable,则可以将结果强制转换为以下形式:
public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty, bool desc)
{
string command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExpression));
return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExpression);
}
Run Code Online (Sandbox Code Playgroud)
这是我为处理条件降序而提出的一些方法。您可以将其与其他keySelector
动态生成func 的方法结合使用。
public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source,
System.Linq.Expressions.Expression<Func<TSource, TKey>> keySelector,
System.ComponentModel.ListSortDirection sortOrder
)
{
if (sortOrder == System.ComponentModel.ListSortDirection.Ascending)
return source.OrderBy(keySelector);
else
return source.OrderByDescending(keySelector);
}
Run Code Online (Sandbox Code Playgroud)
用法:
//imagine this is some parameter
var direction = System.ComponentModel.ListSortDirection.Ascending;
query = query.OrderBy(ec => ec.MyColumnName, direction);
Run Code Online (Sandbox Code Playgroud)
请注意,这允许您将此.OrderBy
扩展与新参数链接到任何 IQueryable 上。
// perhaps passed in as a request of user to change sort order
// var direction = System.ComponentModel.ListSortDirection.Ascending;
query = context.Orders
.Where(o => o.Status == OrderStatus.Paid)
.OrderBy(ec => ec.OrderPaidUtc, direction);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
72063 次 |
最近记录: |