从字符串属性名称创建通用表达式

我有一个名为sortColumn的变量,它包含我想要对查询结果进行排序的列的文本。 我还有一个通用存储库,它将包含我想要排序的字段的Expression作为参数。 我似乎无法从字符串属性名称获取到表达式。

所以我拥有的通用存储库包含以下方法

public IEnumerable Get(Expression<Func> criteria, Expression<Func> orderBy, int pageIndex, int pageSize, bool isAssendingOrder = true, EnumDeletePolicy deletePolicy = EnumDeletePolicy.ExcludeDeleted) 

注意这个Get的第二个参数是Expression-Func-TEntity,TOrderBy。 正如我所提到的,我有一个名为sortColumn的变量,它包含我的TEntity对象上的属性的字符串,我需要将此字符串转换为可以传递给Get方法的Expression。

这就是我现在所拥有的。

  var parameter = Expression.Parameter(typeof(IContract)); var memberExpression = Expression.Property(parameter, data.SortColumn); var lambdaExpression = Expression.Lambda(memberExpression, parameter); 

这将创建LambdaExpression类型的对象。 此LambdaExpression的实际类型是Expression-Func-IContract,字符串(或属性的sortColumn类型)。 如果我调用Get方法并传入此LambdaExpression并将其显​​式转换为Expression类型,那么它将正常工作。 问题是我不知道Expression类型是什么,它可能是一个字符串,int,int?等等。这完全取决于sortColumn属性中特定属性的类型。

你能帮助我最后跳到正确的Expression类型吗?

根据Marc的建议编辑:我几乎有这个工作,实际上基于它正在工作的问题,但我有1个剩余的问题。

作为我要查询的实体类型的IContract实际上是从IRelationshipinheritance的。 如果我从IContract接口指定一个字段,那么上面的代码可以工作。 如果我从IRelationship接口指定一个字段,则以下行失败。

  var memberExpression = Expression.Property(parameter, data.SortColumn); 

如果我尝试下面这样的东西,以便从IRelationship中获取MemberExpression,但是基于IContract构建Lambda,我会从存储库中收到错误。

  var parameter = Expression.Parameter(typeof(IRelationship)); var memberExpression = Expression.Property(parameter, data.SortColumn); var orderBy = Expression.Lambda(memberExpression, Expression.Parameter(typeof(IContract))); 

我得到的错误是“参数”没有绑定在指定的LINQ to Entities查询表达式中。”

让它运作的最终表达是这样的

  var parameter = Expression.Parameter(typeof(IContract)); var memberExpression = Expression.Property(parameter, typeof(IRelationship), data.SortColumn); var orderBy = Expression.Lambda(memberExpression, parameter); 

所以我需要为memberExpression行指定middle参数,以便查看属性的inheritanceRelationship接口

你需要使用正确的generics重载 – 这曾经意味着你必须使用MakeGenericMethod ; 但是,您也可以使用dynamic来避免在这里使用MakeGenericMethod (例如,通过Where ,但重要的是它是如何工作的):

 IQueryable source = new[] { new Foo { Bar = 123 } }.AsQueryable(); Expression> typed = x=>x.Bar == 123; LambdaExpression untyped = typed; IQueryable filtered = Queryable.Where(source, (dynamic)untyped); 

注意:您不能在此处使用扩展方法 – 因此您需要使用Queryable.*

对于使用您的代码的OrderBy示例:

 var parameter = Expression.Parameter(typeof(Foo)); var memberExpression = Expression.Property(parameter, "Bar"); var lambdaExpression = Expression.Lambda(memberExpression, parameter); LambdaExpression untyped = lambdaExpression; IQueryable sorted = Queryable.OrderBy(source, (dynamic)untyped); var all = sorted.ToArray(); 

重新编辑:

 var parameter = Expression.Parameter(typeof(IRelationship)); var memberExpression = Expression.Property( Expression.Convert(parameter, typeof(IContract)), data.SortColumn); var orderBy = Expression.Lambda(memberExpression, parameter);