C# 动态Lambda表达式,用于使用c语言的子级进行筛选和排序#
您好,我按照中的指南在关系类中创建过滤器和排序,我需要使用子列“通道”进行过滤和排序 这是我的基础课C# 动态Lambda表达式,用于使用c语言的子级进行筛选和排序#,c#,lambda,expression-trees,linq-expressions,ef-core-2.0,C#,Lambda,Expression Trees,Linq Expressions,Ef Core 2.0,您好,我按照中的指南在关系类中创建过滤器和排序,我需要使用子列“通道”进行过滤和排序 这是我的基础课 public class MeterTransaction : EviModelBase { public int TariffDuration { get; set; } public decimal? TariffPackageKwh { get; set; } public decimal? TariffPackagePrice { get; set
public class MeterTransaction : EviModelBase
{
public int TariffDuration { get; set; }
public decimal? TariffPackageKwh { get; set; }
public decimal? TariffPackagePrice { get; set; }
public decimal? TariffRatePerKwh { get; set; }
public decimal? TariffRateMinFee { get; set; }
// Meter CreditBalance after transaction
public decimal CreditBalance { get; set; }
public DateTimeOffset? CreditExpiration { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
public Meter Meter { get; set; }
}
这是米级
public class Meter : EviModelBase
{
public MeterVendor Vendor { get; set; }
public string Model { get; set; }
public string SerialNumber { get; set; }
public string Channel { get; set; }
}
这是筛选和排序数据的代码:
public static IQueryable<T> OrderByNew<T>(this IQueryable<T> source, SortModel sortModel)
{
ParameterExpression p = Expression.Parameter(typeof(T), "p");
// Construct the nested properties
string[] nestedProps = sortModel.ColId.Split('.');
Expression mbr = p;
for (int i = 0; i < nestedProps.Length; i++)
mbr = Expression.PropertyOrField(mbr, nestedProps[i]);
LambdaExpression pred = Expression.Lambda(
Expression.Equal(
mbr,
Expression.Constant("EVI0000101")
),
p
);
var method = string.Equals(sortModel.Sort, "desc", StringComparison.OrdinalIgnoreCase) ?
"OrderByDescending" :
"OrderBy";
var whereCallExpression = Expression.Call(typeof(Queryable), "where", new Type[] { source.ElementType }, source.Expression, pred);
var orderByExpression = Expression.Lambda(mbr, p);
MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
method,
new Type[] { source.ElementType},
whereCallExpression,
Expression.Quote(orderByExpression));
// ***** End OrderBy *****
return source.Provider.CreateQuery<T>(orderByCallExpression);
}
}
公共静态IQueryable OrderByNew(此IQueryable源,SortModel SortModel)
{
ParameterExpression p=表达式参数(类型为(T),“p”);
//构造嵌套属性
字符串[]nestedProps=sortModel.ColId.Split('.');
表达mbr=p;
for(int i=0;i
实际上,“whereCallExpression”正在运行并过滤我想要的数据,没有错误,但是排序逻辑给出了一个错误“没有类型系统上的泛型方法'OrderBy'。Linq.Queryable'与提供的类型参数和参数兼容。”
我怎样才能做到这一点
与
Where
相比,OrderBy
方法有两个泛型类型参数(TSource
和TKey
)。因此,在生成呼叫时,您需要同时提供这两个选项:
var orderByCallExpression = Expression.Call(
typeof(Queryable),
method,
new Type[] { source.ElementType, orderByExpression.Body.Type }, // <--
whereCallExpression,
Expression.Quote(orderByExpression));
var orderByCallExpression=Expression.Call(
类型(可查询),
方法,,
新类型[]{source.ElementType,orderByExpression.Body.Type},//thx这解决了我的问题,顺便说一句,是否可以将筛选器表达式从“==”更改为“like”或“contains”当然,而不是表达式。Equal
您可以使用表达式。调用(mbr,“contains”,Type.EmptyTypes,Expression.Constant(“EVI0000101”))
再一次,thx@Ivan Stoev,有关于这方面的有用文档吗?据我所知,它可以帮助我很多。我所有的经验都来自自我学习和实验。探索表达式
类静态方法。或者在大多数情况下,创建示例编译时表达式更容易(例如,Expression expr=x=>x.Bar.Contains(“Baz”);
并检查调试器中的内容。然后找到适当的静态方法动态构建它:)