如何有条件地将 LINQ OrderByDescending 中的列用于 OrderBy?
How to Conditionally the column in LINQ OrderByDescending for OrderBy?
如何使用 LINQ OrderBy 子句有条件地对列进行排序。
ex- 我有一个 属性 Filter.OrderBy
和 Filter.Order
。 OrderBy
中可能有很多 ex> 名称、地址、城市等,Order
将按升序或降序排列,但我不确定如何使用条件列对其进行排序。
请参考以下代码:
IQueryable<Filter> query;
PropertyInfo prop = typeof(Filter).GetProperty(Filter.OrderBy);
if (Filter.Order ==" Ascending"){
query = query.OrderBy ( x = > prop.GetValue(x,null));
}
else if (Filter.Order ==" Descending"){
query = query.OrderByDescending ( x = > prop.GetValue(x,null));
}
但是查询失败。我不确定我可以使用反射看到道具 属性 的问题是什么
但是表达式 prop.GetValue 不起作用。
请帮我解决这个问题。
我创建了这个示例,也许它可以帮助你
IEnumerable<Person> q = new List<Person>
{
new Person{Name = "C", Age = 3 },
new Person{Name = "A", Age = 7 },
new Person{Name = "B", Age = 5 }
};
var props = new[] { "Name", "Age" };
var orders = new[] { "Ascending", "Descending" };
foreach (var prop in props)
{
var property = typeof(Person).GetProperty(prop);
foreach (var order in orders)
{
IEnumerable<Person> q2 = null;
if (order == "Ascending")
{ q2 = q.OrderBy(p => property.GetValue(p)); }
else
{ q2 = q.OrderByDescending(p => property.GetValue(p)); }
Console.WriteLine("Property: {0}, Order: {1}", prop, order);
foreach (var p in q2)
{
Console.WriteLine("Name: {0}, Age: {1}", p.Name, p.Age);
}
Console.WriteLine();
}
}
输出:
Property: Name, Order: Ascending
Name: A, Age: 7
Name: B, Age: 5
Name: C, Age: 3
Property: Name, Order: Descending
Name: C, Age: 3
Name: B, Age: 5
Name: A, Age: 7
Property: Age, Order: Ascending
Name: C, Age: 3
Name: B, Age: 5
Name: A, Age: 7
Property: Age, Order: Descending
Name: A, Age: 7
Name: B, Age: 5
Name: C, Age: 3
将属性设置为参数。
示例:
var param = "Address";
var propertyInfo = typeof(Filter).GetProperty(param);
var orderByAddress = items.OrderBy(x => propertyInfo.GetValue(x, null));
public static class LinqUtils
{
/// <summary>
/// Orders the by.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <param name="direction">The direction.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderBy<T>(this IMongoQueryable<T> source, string propertyName, OrderDirection direction)
{
switch (direction)
{
case OrderDirection.ASC:
return source.OrderBy(ToLambda<T>(propertyName));
case OrderDirection.DESC:
return source.OrderByDescending(ToLambda<T>(propertyName));
default:
return source.OrderBy(ToLambda<T>(propertyName));
}
}
/// <summary>
/// Orders the by.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <param name="direction">The direction.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderBy<T>(this IMongoQueryable<T> source, string propertyName, int direction)
{
var dir = (OrderDirection)direction;
switch (dir)
{
case OrderDirection.ASC:
return source.OrderBy(ToLambda<T>(propertyName));
case OrderDirection.DESC:
return source.OrderByDescending(ToLambda<T>(propertyName));
default:
return source.OrderBy(ToLambda<T>(propertyName));
}
}
/// <summary>
/// Orders the by.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderBy<T>(this IMongoQueryable<T> source, string propertyName)
{
return source.OrderBy(ToLambda<T>(propertyName));
}
/// <summary>
/// Orders the by descending.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderByDescending<T>(this IMongoQueryable<T> source, string propertyName)
{
return source.OrderByDescending(ToLambda<T>(propertyName));
}
/// <summary>
/// Wheres the specified property name.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <param name="stringToSource">The string to source.</param>
/// <returns></returns>
public static IMongoQueryable<T> Where<T>(this IMongoQueryable<T> source, string propertyName, string stringToSource)
{
return source.Where(ToLambdaWhere<T>(propertyName, stringToSource));
}
/// <summary>
/// Wheres the text.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query">The query.</param>
/// <param name="field">The field.</param>
/// <param name="search">The search.</param>
/// <returns></returns>
public static IMongoQueryable<T> WhereText<T>(this IMongoQueryable<T> query, Expression<Func<T, object>> field, string search)
{
search = Regex.Escape(search);
var filter = Builders<T>.Filter.Text(search);
var member = HelpersLinq.PropertyName<T>(field);
var regexFilter = string.Format("^{0}.*", search);
var filterRegex = Builders<T>.Filter.Regex(member, BsonRegularExpression.Create(new Regex(regexFilter, RegexOptions.IgnoreCase)));
return query.Where(_ => filter.Inject() && filterRegex.Inject());
}
/// <summary>
/// Converts to lambda.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
private static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var parameter = Expression.Parameter(typeof(T));
var property = Expression.Property(parameter, propertyName);
var propAsObject = Expression.Convert(property, typeof(object));
return Expression.Lambda<Func<T, object>>(propAsObject, parameter);
}
/// <summary>
/// Converts to lambdawhere.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyName">Name of the property.</param>
/// <param name="stringToSearch">The string to search.</param>
/// <returns></returns>
private static Expression<Func<T, bool>> ToLambdaWhere<T>(string propertyName, string stringToSearch)
{
//var parameter = Expression.Parameter(typeof(T));
// Create a parameter to use for both of the expression bodies.
var parameter = Expression.Parameter(typeof(T), "x");
// Invoke each expression with the new parameter, and combine the expression bodies with OR.
var predicate = Expression.Lambda<Func<T, bool>>(Expression.Call(Expression.PropertyOrField(parameter, propertyName), "Contains", null, Expression.Constant(stringToSearch)), parameter);
return predicate;
}
}
public static class HelpersLinq
{
public static string PropertyName<T>(Expression<Func<T, object>> expression)
{
var member = expression.Body as MemberExpression;
if (member != null && member.Member is PropertyInfo)
return member.Member.Name;
throw new ArgumentException("Expression is not a Property", "expression");
}
}
public enum OrderDirection
{
ASC = 1,
DESC
}
所以你可以像这样使用它:
initialQuery.OrderBy("Name", OrderDirection.ASC)
希望对您有所帮助!
您可以使用支持动态查询、选择和排序的库System.Linq.Dynamic.Core。
示例代码:
var q = new List<Person>
{
new Person{Name = "C", Age = 30 },
new Person{Name = "A", Age = 7 },
new Person{Name = "B", Age = 5 }
}.AsQueryable();
var x1 = q.OrderBy("Name asc");
var a1 = q.OrderBy("Age desc");
有关完整的工作示例,请参阅 dotnetfiddle
从 nuget
下载 Linq.Dynamic
使用 ex 添加:
using System.Linq.Dynamic
使用此代码
query = query.OrderBy(Colum name + " " + ASC OR DESC);
如何使用 LINQ OrderBy 子句有条件地对列进行排序。
ex- 我有一个 属性 Filter.OrderBy
和 Filter.Order
。 OrderBy
中可能有很多 ex> 名称、地址、城市等,Order
将按升序或降序排列,但我不确定如何使用条件列对其进行排序。
请参考以下代码:
IQueryable<Filter> query;
PropertyInfo prop = typeof(Filter).GetProperty(Filter.OrderBy);
if (Filter.Order ==" Ascending"){
query = query.OrderBy ( x = > prop.GetValue(x,null));
}
else if (Filter.Order ==" Descending"){
query = query.OrderByDescending ( x = > prop.GetValue(x,null));
}
但是查询失败。我不确定我可以使用反射看到道具 属性 的问题是什么 但是表达式 prop.GetValue 不起作用。
请帮我解决这个问题。
我创建了这个示例,也许它可以帮助你
IEnumerable<Person> q = new List<Person>
{
new Person{Name = "C", Age = 3 },
new Person{Name = "A", Age = 7 },
new Person{Name = "B", Age = 5 }
};
var props = new[] { "Name", "Age" };
var orders = new[] { "Ascending", "Descending" };
foreach (var prop in props)
{
var property = typeof(Person).GetProperty(prop);
foreach (var order in orders)
{
IEnumerable<Person> q2 = null;
if (order == "Ascending")
{ q2 = q.OrderBy(p => property.GetValue(p)); }
else
{ q2 = q.OrderByDescending(p => property.GetValue(p)); }
Console.WriteLine("Property: {0}, Order: {1}", prop, order);
foreach (var p in q2)
{
Console.WriteLine("Name: {0}, Age: {1}", p.Name, p.Age);
}
Console.WriteLine();
}
}
输出:
Property: Name, Order: Ascending
Name: A, Age: 7
Name: B, Age: 5
Name: C, Age: 3
Property: Name, Order: Descending
Name: C, Age: 3
Name: B, Age: 5
Name: A, Age: 7
Property: Age, Order: Ascending
Name: C, Age: 3
Name: B, Age: 5
Name: A, Age: 7
Property: Age, Order: Descending
Name: A, Age: 7
Name: B, Age: 5
Name: C, Age: 3
将属性设置为参数。 示例:
var param = "Address";
var propertyInfo = typeof(Filter).GetProperty(param);
var orderByAddress = items.OrderBy(x => propertyInfo.GetValue(x, null));
public static class LinqUtils
{
/// <summary>
/// Orders the by.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <param name="direction">The direction.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderBy<T>(this IMongoQueryable<T> source, string propertyName, OrderDirection direction)
{
switch (direction)
{
case OrderDirection.ASC:
return source.OrderBy(ToLambda<T>(propertyName));
case OrderDirection.DESC:
return source.OrderByDescending(ToLambda<T>(propertyName));
default:
return source.OrderBy(ToLambda<T>(propertyName));
}
}
/// <summary>
/// Orders the by.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <param name="direction">The direction.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderBy<T>(this IMongoQueryable<T> source, string propertyName, int direction)
{
var dir = (OrderDirection)direction;
switch (dir)
{
case OrderDirection.ASC:
return source.OrderBy(ToLambda<T>(propertyName));
case OrderDirection.DESC:
return source.OrderByDescending(ToLambda<T>(propertyName));
default:
return source.OrderBy(ToLambda<T>(propertyName));
}
}
/// <summary>
/// Orders the by.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderBy<T>(this IMongoQueryable<T> source, string propertyName)
{
return source.OrderBy(ToLambda<T>(propertyName));
}
/// <summary>
/// Orders the by descending.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
public static IOrderedMongoQueryable<T> OrderByDescending<T>(this IMongoQueryable<T> source, string propertyName)
{
return source.OrderByDescending(ToLambda<T>(propertyName));
}
/// <summary>
/// Wheres the specified property name.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="propertyName">Name of the property.</param>
/// <param name="stringToSource">The string to source.</param>
/// <returns></returns>
public static IMongoQueryable<T> Where<T>(this IMongoQueryable<T> source, string propertyName, string stringToSource)
{
return source.Where(ToLambdaWhere<T>(propertyName, stringToSource));
}
/// <summary>
/// Wheres the text.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query">The query.</param>
/// <param name="field">The field.</param>
/// <param name="search">The search.</param>
/// <returns></returns>
public static IMongoQueryable<T> WhereText<T>(this IMongoQueryable<T> query, Expression<Func<T, object>> field, string search)
{
search = Regex.Escape(search);
var filter = Builders<T>.Filter.Text(search);
var member = HelpersLinq.PropertyName<T>(field);
var regexFilter = string.Format("^{0}.*", search);
var filterRegex = Builders<T>.Filter.Regex(member, BsonRegularExpression.Create(new Regex(regexFilter, RegexOptions.IgnoreCase)));
return query.Where(_ => filter.Inject() && filterRegex.Inject());
}
/// <summary>
/// Converts to lambda.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
private static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var parameter = Expression.Parameter(typeof(T));
var property = Expression.Property(parameter, propertyName);
var propAsObject = Expression.Convert(property, typeof(object));
return Expression.Lambda<Func<T, object>>(propAsObject, parameter);
}
/// <summary>
/// Converts to lambdawhere.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyName">Name of the property.</param>
/// <param name="stringToSearch">The string to search.</param>
/// <returns></returns>
private static Expression<Func<T, bool>> ToLambdaWhere<T>(string propertyName, string stringToSearch)
{
//var parameter = Expression.Parameter(typeof(T));
// Create a parameter to use for both of the expression bodies.
var parameter = Expression.Parameter(typeof(T), "x");
// Invoke each expression with the new parameter, and combine the expression bodies with OR.
var predicate = Expression.Lambda<Func<T, bool>>(Expression.Call(Expression.PropertyOrField(parameter, propertyName), "Contains", null, Expression.Constant(stringToSearch)), parameter);
return predicate;
}
}
public static class HelpersLinq
{
public static string PropertyName<T>(Expression<Func<T, object>> expression)
{
var member = expression.Body as MemberExpression;
if (member != null && member.Member is PropertyInfo)
return member.Member.Name;
throw new ArgumentException("Expression is not a Property", "expression");
}
}
public enum OrderDirection
{
ASC = 1,
DESC
}
所以你可以像这样使用它:
initialQuery.OrderBy("Name", OrderDirection.ASC)
希望对您有所帮助!
您可以使用支持动态查询、选择和排序的库System.Linq.Dynamic.Core。
示例代码:
var q = new List<Person>
{
new Person{Name = "C", Age = 30 },
new Person{Name = "A", Age = 7 },
new Person{Name = "B", Age = 5 }
}.AsQueryable();
var x1 = q.OrderBy("Name asc");
var a1 = q.OrderBy("Age desc");
有关完整的工作示例,请参阅 dotnetfiddle
从 nuget
下载Linq.Dynamic
使用 ex 添加:
using System.Linq.Dynamic
使用此代码
query = query.OrderBy(Colum name + " " + ASC OR DESC);