2011-10-22 64 views
6

我想创建一个表达式树。我需要从数据表中读取数据并检查其列。只有在运行时才知道要检查的列以及要检查的列数。列名以字符串数组的形式给予我,并且每列都有一个要检查的字符串列表。我尝试了以下示例表达式树。错误静态方法需要空实例,非静态方法需要非空实例

这里我遇到了一个错误。

静态方法需要空实例,非静态方法需要非空实例。 参数名称:实例

在线路

内= Expression.Call(rowexp,MI,colexp);

请帮助我!

IQueryable<DataRow> queryableData = CapacityTable 
    .AsEnumerable() 
    .AsQueryable() 
    .Where(row2 => values.Contains(row2.Field<string>("Head1").ToString()) 
       && values.Contains(row2.Field<string>("Head2").ToString())); 

MethodInfo mi = typeof(DataRowExtensions).GetMethod(
    "Field", 
     new Type[] { typeof(DataRow),typeof(string) }); 

mi = mi.MakeGenericMethod(typeof(string)); 

ParameterExpression rowexp = Expression.Parameter(typeof(DataRow), "row"); 
ParameterExpression valuesexp = Expression.Parameter(typeof(List<string>), "values"); 
ParameterExpression fexp = Expression.Parameter(typeof(List<string>), "types"); 
Expression inner, outer, predicateBody = null; 

foreach (var col in types) 
{ 
    // DataRow row = CapacityTable.Rows[1]; 

    ParameterExpression colexp = Expression.Parameter(typeof(string), "col"); 
    // Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes)); 

    inner = Expression.Call(rowexp,mi, colexp); 
    outer = Expression.Call(valuesexp, typeof(List<string>).GetMethod("Contains"), inner); 
    predicateBody = Expression.And(predicateBody,outer); 
} 

MethodCallExpression whereCallExpression = Expression.Call(
    typeof(Queryable), 
    "Where", 
    new Type[] { queryableData.ElementType }, 
    queryableData.Expression, 
    Expression.Lambda<Func<DataRow,bool>>(predicateBody, new ParameterExpression[] { rowexp })); 

回答

9

这意味着该方法调用你要代表的是静态的,但你给它的目标表达。这就像试图拨打电话:

Thread t = new Thread(...); 
// Invalid! 
t.Sleep(1000); 

你有点试图在表达式树形式,这是不允许的。

它看起来像发生这种情况的Field扩展方法上DataRowExtensions - 这样的扩展方法的“目标”需要被表达为第一参数的号召,因为你真的想拨打:

DataRowExtensions.Field<T>(row, col); 

所以,你想:

inner = Expression.Call(mi, rowexp, colexp); 

,将调用this overload这是调用静态方法有两个参数的方式。

+0

你可能可以详细介绍一下上面的内容吗?为什么在这里将Expression info作为第一个参数传递给Expression.Call方法? – Kobojunkie

+0

@Kobojunkie:因为这就是你如何告诉'Expression.Call'我们感兴趣的静态方法。请参阅http://msdn.microsoft.com/en-us/library/bb301084.aspx –

相关问题