C# LINQ方法,它根据我发送的列名对数据进行动态排序
我想做什么? 我想创建一个方法,它根据我发送的列名对数据进行动态排序 首先,我创建了一个用于测试的项目。我看这个项目做得很好 测试项目:C# LINQ方法,它根据我发送的列名对数据进行动态排序,c#,linq,asp.net-core,.net-core,C#,Linq,Asp.net Core,.net Core,我想做什么? 我想创建一个方法,它根据我发送的列名对数据进行动态排序 首先,我创建了一个用于测试的项目。我看这个项目做得很好 测试项目: PropertyInfo pinfo=typeof(MockData).GetProperty(orderColumn); 开关(订单方向) { 案例“asc”: mockDataList=q.OrderBy(o=>pinfo.GetValue(o,null)).Skip(start.Take(length.ToList(); 打破 案例“desc”: moc
PropertyInfo pinfo=typeof(MockData).GetProperty(orderColumn);
开关(订单方向)
{
案例“asc”:
mockDataList=q.OrderBy(o=>pinfo.GetValue(o,null)).Skip(start.Take(length.ToList();
打破
案例“desc”:
mockDataList=q.OrderByDescending(o=>pinfo.GetValue(o,null)).Skip(start.Take(length.ToList();
打破
}
之后,我将学到的东西应用到我的基本项目中:
基本项目:
publicIQueryable重构QueryBagination(DataTablesRequestModelDataTablesRequestModel,IQueryable查询)
{
PropertyInfo pinfo=typeof(T).GetProperty(dataTablesRequestModel.OrderColumn);
开关(dataTablesRequestModel.OrderDirection)
{
案例“asc”:
query=query.OrderBy(o=>pinfo.GetValue(o,null)!=null);
打破
案例“desc”:
query=query.OrderByDescending(o=>pinfo.GetValue(o,null)!=null);
打破
}
query=query.Skip(datatablerequestmodel.Start);
query=query.Take(datatablerequestmodel.Length);
var test=query.ToList();
返回查询;
}
但它不工作,它给了我一个错误(“无法翻译…”)
我尝试的解决方案
公共静态IQueryable OrderBy(此IQueryable项,字符串propertyName)
{
var typeOfT=typeof(T);
var参数=表达式参数(typeOfT,“参数”);
var propertyType=typeOfT.GetProperty(propertyName).propertyType;
var propertyAccess=Expression.PropertyOrField(参数,propertyName);
var orderExpression=Expression.Lambda(propertyAccess,参数);
var expression=expression.Call(typeof(Queryable),“OrderBy”,新类型[]{typeOfT,propertyType},items.expression,expression.Quote(orderExpression));
返回items.Provider.CreateQuery(表达式);
}
它可以工作,但我不能操纵表达式。(如o=>o.Column.HasValue
)
一整天,我都在做这个,我真的很累。有人能帮我吗?您可以使用以更简单的方式实现您正在尝试的目标。你可以在这里找到NuGet软件包-
根据您的代码,我假设您的场景不涉及对多个列进行排序/排序。如果是这样,您可以创建一个扩展方法,如下所示-
//您需要添加此
//使用System.Linq.Dynamic.Core;
公共静态类IQueryableExtension
{
公共静态IQueryable ApplyOrder(此IQueryable源、字符串列、字符串方向)
{
if(string.IsNullOrWhiteSpace(column))
返回源;
var pinfo=typeof(T).GetProperty(列);
if(pinfo==null)
返回源;
变量顺序=(方向==“desc”)?$“{column}desc”:列;
返回source.OrderBy(订单);
}
}
您可以从现有代码中使用它,如-
publicIQueryable重构QueryBagination(DataTablesRequestModelDataTablesRequestModel,IQueryable查询)
{
//这是电话
query=query.ApplyOrder(dataTablesRequestModel.OrderColumn,dataTablesRequestModel.OrderDirection);
query=query.Skip(datatablerequestmodel.Start);
query=query.Take(datatablerequestmodel.Length);
var test=query.ToList();
返回查询;
}
您可以使用来以更简单的方式实现您想要做的事情。你可以在这里找到NuGet软件包-
根据您的代码,我假设您的场景不涉及对多个列进行排序/排序。如果是这样,您可以创建一个扩展方法,如下所示-
//您需要添加此
//使用System.Linq.Dynamic.Core;
公共静态类IQueryableExtension
{
公共静态IQueryable ApplyOrder(此IQueryable源、字符串列、字符串方向)
{
if(string.IsNullOrWhiteSpace(column))
返回源;
var pinfo=typeof(T).GetProperty(列);
if(pinfo==null)
返回源;
变量顺序=(方向==“desc”)?$“{column}desc”:列;
返回source.OrderBy(订单);
}
}
您可以从现有代码中使用它,如-
publicIQueryable重构QueryBagination(DataTablesRequestModelDataTablesRequestModel,IQueryable查询)
{
//这是电话
query=query.ApplyOrder(dataTablesRequestModel.OrderColumn,dataTablesRequestModel.OrderDirection);
query=query.Skip(datatablerequestmodel.Start);
query=query.Take(datatablerequestmodel.Length);
var test=query.ToList();
返回查询;
}
尝试使用以下代码创建QueryableExtensions:
//required using System.Linq;
//required using System.Linq.Expressions;
public static class QueryableExtensions
{
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string columnName, bool isAscending = true)
{
if (String.IsNullOrEmpty(columnName))
{
return source;
}
ParameterExpression parameter = Expression.Parameter(source.ElementType, "");
MemberExpression property = Expression.Property(parameter, columnName);
LambdaExpression lambda = Expression.Lambda(property, parameter);
string methodName = isAscending ? "OrderBy" : "OrderByDescending";
Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,
new Type[] { source.ElementType, property.Type },
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<T>(methodCallExpression);
}
屏幕截图如下:
尝试使用以下代码创建QueryableExtensions:
//required using System.Linq;
//required using System.Linq.Expressions;
public static class QueryableExtensions
{
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string columnName, bool isAscending = true)
{
if (String.IsNullOrEmpty(columnName))
{
return source;
}
ParameterExpression parameter = Expression.Parameter(source.ElementType, "");
MemberExpression property = Expression.Property(parameter, columnName);
LambdaExpression lambda = Expression.Lambda(property, parameter);
string methodName = isAscending ? "OrderBy" : "OrderByDescending";
Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,
new Type[] { source.ElementType, property.Type },
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<T>(methodCallExpression);
}
屏幕截图如下:
从您的“测试”项目中学习了
.OrderBy(o=>pinfo.GetValue(o,null))
。然后在您的“基本”项目中使用.OrderBy(o=>pinfo.GetValue(o,null)!=null)。然后使用.OrderBy(o=>pinfo.GetValue(o,null))
。为什么?另外pinfo.GetValue(o,null)!=null
将返回一个bool
值。为什么要按true
或false
排序?通常所有查询逻辑都是使用LINQ编写的,但当您将其设置为动态时,所有查询逻辑都必须以其他格式表示。这里只有一个字符串表示要排序的列,因此只能构建要排序的表达式。如果你有更多的要求,首先你需要弄清楚是哪个argu