【问题标题】:Dynamic Data - Implementing IQueryable for List<int> Contains()动态数据 - 为 List<int> Contains() 实现 IQueryable
【发布时间】:2013-05-07 15:05:33
【问题描述】:

我有一系列对象,它们都具有相似的属性,即它们所属组的 Id 列表(每个孩子有许多父母)。

我无法以编程方式实现使此过滤器正常工作所需的 Linq 表达式。

这是我目前所拥有的:

IQueryable result = null;

   if (!string.IsNullOrWhiteSpace(this.ddlRouteNames.SelectedValue))
   {
      ConstantExpression ce = Expression.Constant(int.Parse(this.ddlRouteNames.SelectedValue));
      ParameterExpression pe = Expression.Parameter(source.ElementType);
      MemberExpression me = Expression.Property(pe, this.Column.Name);
      MethodCallExpression mce = Expression.Call(typeof(List<int>), "Contains", new[] { typeof(int) }, me, ce);

      result = source.Provider.CreateQuery(mce);
   }

return result;

我在尝试创建 MethodCallExpression 时遇到异常:

类型“System.Collections.Generic.List`1[System.Int32]”上不存在方法“包含”。

任何关于从哪里开始的指针?

【问题讨论】:

  • 我很困惑,你在your previous question 中几乎是正确的。
  • 在这个问题中,方法是静态的。
  • 其他问题在我尝试创建查询时导致异常:“Argument expression does not implement System.Linq.IQueryable`1[System.Boolean].”

标签: c# asp.net dynamic-data linq-expressions


【解决方案1】:

您的方法调用不正确,要调用非静态方法,您需要提供包含该方法的实例。这是Contains方法调用的例子:

var list = new List<int> {1};
//Target for invoke method
var target = Expression.Constant(list);
var methodCallExpression = Expression.Call(target, typeof(List<int>).GetMethod("Contains"), Expression.Constant(1));

如果您的代码 me 是包含 List 的成员,则代码将如下所示:

Expression.Call(me, typeof(List<int>).GetMethod("Contains"), ce);

【讨论】:

  • 越来越近... MethodCallExpression 部分现在似乎可以正常工作,但是当我尝试使用 IQueryable 源来创建查询时,我得到了这个异常:“参数表达式没有实现 System. Linq.IQueryable`1[System.Boolean]。”
  • source 变量的类型是什么?
  • source 是一个传递给 GetQueryable 方法的 IQueryable,它被 QueryableFilterUserControl 的继承覆盖。
【解决方案2】:

您使用的方法签名中的Type

public static MethodCallExpression Call(Type type, 
                                        string methodName, 
                                        Type[] typeArguments, 
                                        params Expression[] arguments);

指定包含特定静态方法的类型。

您需要此方法的类型实例可用 - 一个示例(与您的评论相关):

var par = Expression.Parameter(typeof(int), "par");            
var inst = Expression.Parameter(typeof(List<int>), "inst");
var body = Expression.Call(inst, typeof(List<int>).GetMethod("Contains"), par);
var exp = Expression.Lambda(body, inst, par);
var deleg = exp.Compile();

var lst = new List<int>() { 1, 2, 3, 4, 5 };
var exists = deleg.DynamicInvoke(lst, 3);

【讨论】:

  • 谢谢。我可以使用类似的东西来达到预期的效果吗?我实际上是在尝试编写一个表达式,以查看所选 ID 是否出现在此对象的 ID 列表 中。
猜你喜欢
  • 2011-10-09
  • 2012-01-07
  • 2013-11-22
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
相关资源
最近更新 更多