Pau*_*cas 17 c# generics expression
我有一个名为sortColumn的变量,它包含我想要对查询结果进行排序的列的文本.我还有一个通用存储库,它将包含我想要排序的字段的Expression作为参数.我似乎无法从字符串属性名称获取到Expression.
所以我拥有的通用存储库包含以下方法
public IEnumerable<TEntity> Get<TOrderBy>(Expression<Func<TEntity, bool>> criteria,
Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex,
int pageSize,
bool isAssendingOrder = true,
EnumDeletePolicy deletePolicy = EnumDeletePolicy.ExcludeDeleted)
Run Code Online (Sandbox Code Playgroud)
注意这个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);
Run Code Online (Sandbox Code Playgroud)
这将创建LambdaExpression类型的对象.此LambdaExpression的实际类型是Expression-Func-IContract,字符串(或属性的sortColumn类型).如果我调用Get方法并传入此LambdaExpression并将其显式转换为Expression类型,那么它将正常工作.问题是我不知道Expression类型是什么,它可能是一个字符串,int,int?等等.这完全取决于sortColumn属性中特定属性的类型.
你能帮我把最后一次跳转到正确的Expression类型吗?
根据Marc的建议编辑:我几乎有这个工作,实际上基于它正在工作的问题,但我有1个剩余的问题.
作为我要查询的实体类型的IContract实际上是从IRelationship继承的.如果我从IContract接口指定一个字段,那么上面的代码可以工作.如果我从IRelationship接口指定一个字段,则以下行失败.
var memberExpression = Expression.Property(parameter, data.SortColumn);
Run Code Online (Sandbox Code Playgroud)
如果我尝试下面这样的东西,以便我从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)));
Run Code Online (Sandbox Code Playgroud)
我得到的错误是"参数''未绑定在指定的LINQ to Entities查询表达式中."
让它运作的最终表达是这样的
var parameter = Expression.Parameter(typeof(IContract));
var memberExpression = Expression.Property(parameter, typeof(IRelationship), data.SortColumn);
var orderBy = Expression.Lambda(memberExpression, parameter);
Run Code Online (Sandbox Code Playgroud)
所以我需要为memberExpression行指定middle参数,以便查看属性的继承Relationship接口
Mar*_*ell 18
你需要使用正确的泛型过载 - 这曾经意味着你必须使用MakeGenericMethod; 但是,你也可以使用它dynamic来避免在MakeGenericMethod这里使用,例如(在这种情况下,通过Where,但重要的是它是如何工作的):
IQueryable<Foo> source = new[] { new Foo { Bar = 123 } }.AsQueryable();
Expression<Func<Foo,bool>> typed = x=>x.Bar == 123;
LambdaExpression untyped = typed;
IQueryable<Foo> filtered = Queryable.Where(source, (dynamic)untyped);
Run Code Online (Sandbox Code Playgroud)
注意:您不能在此处使用扩展方法 - 因此您需要使用Queryable.*.
有关OrderBy使用代码的示例:
var parameter = Expression.Parameter(typeof(Foo));
var memberExpression = Expression.Property(parameter, "Bar");
var lambdaExpression = Expression.Lambda(memberExpression, parameter);
LambdaExpression untyped = lambdaExpression;
IQueryable<Foo> sorted = Queryable.OrderBy(source, (dynamic)untyped);
var all = sorted.ToArray();
Run Code Online (Sandbox Code Playgroud)
重新编辑:
var parameter = Expression.Parameter(typeof(IRelationship));
var memberExpression = Expression.Property(
Expression.Convert(parameter, typeof(IContract)), data.SortColumn);
var orderBy = Expression.Lambda(memberExpression, parameter);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7611 次 |
| 最近记录: |