C# 如何动态指定Linq OrderBy参数?
如何使用作为参数的值指定传递给C# 如何动态指定Linq OrderBy参数?,c#,linq,C#,Linq,如何使用作为参数的值指定传递给orderby的参数 例: 这不允许您按照问题中的要求传递字符串,但它可能仍然适用于您 OrderByDescending方法采用Func,因此您可以通过以下方式重写函数: List<Student> QueryStudents<TKey>(Func<Student, TKey> orderBy) { return existingStudents.OrderByDescending(orderBy).ToList();
orderby
的参数
例:
这不允许您按照问题中的要求传递
字符串
,但它可能仍然适用于您
OrderByDescending
方法采用Func
,因此您可以通过以下方式重写函数:
List<Student> QueryStudents<TKey>(Func<Student, TKey> orderBy)
{
return existingStudents.OrderByDescending(orderBy).ToList();
}
列出查询学生(Func orderBy)
{
返回existingStudents.OrderByDescending(orderBy.ToList();
}
OrderByDescending
还有其他重载,它们采用表达式
,和/或IComparer
。您还可以查看它们,看看它们是否对您有用。这不允许您传递您在问题中要求的字符串,但它可能仍然适用于您
OrderByDescending
方法采用Func
,因此您可以通过以下方式重写函数:
List<Student> QueryStudents<TKey>(Func<Student, TKey> orderBy)
{
return existingStudents.OrderByDescending(orderBy).ToList();
}
列出查询学生(Func orderBy)
{
返回existingStudents.OrderByDescending(orderBy.ToList();
}
OrderByDescending
还有其他重载,它们采用表达式
,和/或IComparer
。您还可以查看它们,看看它们是否有什么用处。您可以使用一点反射来构建表达式树,如下所示(这是一种扩展方法):
public静态IQueryable OrderBy(此IQueryable源,字符串orderByProperty,
布尔描述)
{
string command=desc?“OrderByDescending”:“OrderBy”;
变量类型=类型(强度);
var property=type.GetProperty(orderByProperty);
var参数=表达式参数(类型为“p”);
var propertyAccess=Expression.MakeMemberAccess(参数,属性);
var orderByExpression=Expression.Lambda(propertyAccess,参数);
var resultExpression=Expression.Call(typeof(Queryable),command,新类型[]{Type,property.PropertyType},
source.Expression,Expression.Quote(orderByExpression));
返回source.Provider.CreateQuery(resultExpression);
}
orderByProperty
是要按其排序的属性名称,如果将true作为desc
的参数传递,则将按降序排序;否则,将按升序排序
现在,您应该能够执行现有的students.OrderBy(“City”,true)代码>或现有学生。订购人(“城市”,假)代码>您可以使用一点反射来构建表达式树,如下所示(这是一种扩展方法):
public静态IQueryable OrderBy(此IQueryable源,字符串orderByProperty,
布尔描述)
{
string command=desc?“OrderByDescending”:“OrderBy”;
变量类型=类型(强度);
var property=type.GetProperty(orderByProperty);
var参数=表达式参数(类型为“p”);
var propertyAccess=Expression.MakeMemberAccess(参数,属性);
var orderByExpression=Expression.Lambda(propertyAccess,参数);
var resultExpression=Expression.Call(typeof(Queryable),command,新类型[]{Type,property.PropertyType},
source.Expression,Expression.Quote(orderByExpression));
返回source.Provider.CreateQuery(resultExpression);
}
orderByProperty
是要按其排序的属性名称,如果将true作为desc
的参数传递,则将按降序排序;否则,将按升序排序
现在,您应该能够执行现有的students.OrderBy(“City”,true)代码>或现有学生。订购人(“城市”,假)代码>这里有一种可能使用反射
var param = "Address";
var propertyInfo = typeof(Student).GetProperty(param);
var orderByAddress = items.OrderBy(x => propertyInfo.GetValue(x, null));
这里有一个使用反射的可能性
var param = "Address";
var propertyInfo = typeof(Student).GetProperty(param);
var orderByAddress = items.OrderBy(x => propertyInfo.GetValue(x, null));
private Func GetOrderByExpression(字符串sortColumn)
{
Func orderByExpr=null;
如果(!String.IsNullOrEmpty(sortColumn))
{
类型发起人结果类型=类型(T);
if(sponsorResultType.GetProperties().Any(prop=>prop.Name==sortColumn))
{
System.Reflection.PropertyInfo pinfo=sponsorResultType.GetProperty(sortColumn);
orderByExpr=(data=>pinfo.GetValue(data,null));
}
}
返回orderByExpr;
}
公共列表OrderByDir(IEnumerable源、字符串目录、Func OrderByColumn)
{
return dir.ToUpper()=“ASC”?source.OrderBy(OrderByColumn.ToList():source.OrderByDescending(OrderByColumn.ToList()``
}
//调用下面的代码
var orderByExpression=GetOrderByExpression(排序);
var data=OrderByDir(结果记录、SortDirectionString、orderByExpression);
私有函数GetOrderByExpression(字符串或列)
{
Func orderByExpr=null;
如果(!String.IsNullOrEmpty(sortColumn))
{
类型发起人结果类型=类型(T);
if(sponsorResultType.GetProperties().Any(prop=>prop.Name==sortColumn))
{
System.Reflection.PropertyInfo pinfo=sponsorResultType.GetProperty(sortColumn);
orderByExpr=(data=>pinfo.GetValue(data,null));
}
}
返回orderByExpr;
}
公共列表OrderByDir(IEnumerable源、字符串目录、Func OrderByColumn)
{
return dir.ToUpper()=“ASC”?source.OrderBy(OrderByColumn.ToList():source.OrderByDescending(OrderByColumn.ToList()``
}
//调用下面的代码
var orderByExpression=GetOrderByExpression(排序);
var data=OrderByDir(结果记录、SortDirectionString、orderByExpression);
我想到了一些处理条件降序的方法。您可以将其与动态生成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);
}
请注意,这允许您链接此.OrderBy
var param = "Address";
var propertyInfo = typeof(Student).GetProperty(param);
var orderByAddress = items.OrderBy(x => propertyInfo.GetValue(x, null));
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);
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);
}
//imagine this is some parameter
var direction = System.ComponentModel.ListSortDirection.Ascending;
query = query.OrderBy(ec => ec.MyColumnName, direction);
// 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);
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string sortExpression)
{
if (source == null)
throw new ArgumentNullException("source", "source is null.");
if (string.IsNullOrEmpty(sortExpression))
throw new ArgumentException("sortExpression is null or empty.", "sortExpression");
var parts = sortExpression.Split(' ');
var isDescending = false;
var propertyName = "";
var tType = typeof(T);
if (parts.Length > 0 && parts[0] != "")
{
propertyName = parts[0];
if (parts.Length > 1)
{
isDescending = parts[1].ToLower().Contains("esc");
}
PropertyInfo prop = tType.GetProperty(propertyName);
if (prop == null)
{
throw new ArgumentException(string.Format("No property '{0}' on type '{1}'", propertyName, tType.Name));
}
var funcType = typeof(Func<,>)
.MakeGenericType(tType, prop.PropertyType);
var lambdaBuilder = typeof(Expression)
.GetMethods()
.First(x => x.Name == "Lambda" && x.ContainsGenericParameters && x.GetParameters().Length == 2)
.MakeGenericMethod(funcType);
var parameter = Expression.Parameter(tType);
var propExpress = Expression.Property(parameter, prop);
var sortLambda = lambdaBuilder
.Invoke(null, new object[] { propExpress, new ParameterExpression[] { parameter } });
var sorter = typeof(Queryable)
.GetMethods()
.FirstOrDefault(x => x.Name == (isDescending ? "OrderByDescending" : "OrderBy") && x.GetParameters().Length == 2)
.MakeGenericMethod(new[] { tType, prop.PropertyType });
return (IQueryable<T>)sorter
.Invoke(null, new object[] { source, sortLambda });
}
return source;
}
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" : "");
}
}
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;
}
}
}
Dbset.OrderBy(SortHelper.UserApp("firstname").ToStringForOrdering())
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);
}
List<Employee> Employees = GetAllEmployees();
foreach(Employee oEmployee in Employees.ApplyDynamicSort(eEmployeeSort))
{
//do stuff
}
public static IOrderedEnumerable<Employee> ApplyDynamicSort(this List<Employee> lEmployees, Enums.EmployeeSort eEmployeeSort)
{
switch (eEmployeeSort)
{
case Enums.EmployeeSort.Name_ASC:
return lEmployees.OrderBy(x => x.Name);
case Enums.EmployeeSort.Name_DESC:
return lEmployees.OrderByDescending(x => x.Name);
case Enums.EmployeeSort.Department_ASC_Salary_DESC:
return lEmployees.OrderBy(x => x.Department).ThenByDescending(y => y.Salary);
default:
return lEmployees.OrderBy(x => x.Name);
}
}
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);
}
public static IQueryable<T> OrderByDynamic<T>(this IQueryable<T> q, string SortField1, string SortField2, bool Ascending)
{
var param = Expression.Parameter(typeof(T), "p");
var body = GetBodyExp(SortField1, SortField2, param);
var exp = Expression.Lambda(body, param);
string method = Ascending ? "OrderBy" : "OrderByDescending";
Type[] types = new Type[] { q.ElementType, exp.Body.Type };
var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(mce);
}
public static NewExpression GetBodyExp(string field1, string field2, ParameterExpression Parametro)
{
// SE OBTIENE LOS NOMBRES DE LOS TIPOS DE VARIABLE
string TypeName1 = Expression.Property(Parametro, field1).Type.Name;
string TypeName2 = Expression.Property(Parametro, field2).Type.Name;
// SE DECLARA EL TIPO ANONIMO SEGUN LOS TIPOS DE VARIABLES
Type TypeAnonymous = null;
if (TypeName1 == "String")
{
string var1 = "0";
if (TypeName2 == "Int32")
{
int var2 = 0;
var example = new { var1, var2 };
TypeAnonymous = example.GetType();
}
if (TypeName2 == "String")
{
string var2 = "0";
var example = new { var1, var2 };
TypeAnonymous = example.GetType();
}
}
if (TypeName1 == "Int32")
{
int var1 = 0;
if (TypeName2 == "Int32")
{
string var2 = "0";
var example = new { var1, var2 };
TypeAnonymous = example.GetType();
}
if (TypeName2 == "String")
{
string var2 = "0";
var example = new { var1, var2 };
TypeAnonymous = example.GetType();
}
}
//se declaran los TIPOS NECESARIOS PARA GENERAR EL BODY DE LA EXPRESION LAMBDA
MemberExpression[] args = new[] { Expression.PropertyOrField(Parametro, field1), Expression.PropertyOrField(Parametro, field2) };
ConstructorInfo CInfo = TypeAnonymous.GetConstructors()[0];
IEnumerable<MemberInfo> a = TypeAnonymous.GetMembers().Where(m => m.MemberType == MemberTypes.Property);
//BODY
NewExpression body = Expression.New(CInfo, args, TypeAnonymous.GetMembers().Where(m => m.MemberType == MemberTypes.Property));
return body;
}
IQueryable<MyClass> IqMyClass= context.MyClass.AsQueryable();
List<MyClass> ListMyClass= IqMyClass.OrderByDynamic("UserName", "IdMyClass", true).ToList();
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty, bool desc, bool isThenBy = false)
{
string command = isThenBy ? (desc ? "ThenByDescending" : "ThenBy") : (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);
}
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string sqlOrderByList)
{
var ordebyItems = sqlOrderByList.Trim().Split(',');
IQueryable<TEntity> result = source;
bool useThenBy = false;
foreach (var item in ordebyItems)
{
var splt = item.Trim().Split(' ');
result = result.OrderBy(splt[0].Trim(), (splt.Length > 1 && splt[1].Trim().ToLower() == "desc"), useThenBy);
if (useThenBy)
useThenBy = true;
}
return result;
}