2011-10-22 16 views
6

Sto tentando di creare un albero di espressioni. Ho bisogno di leggere i dati da una tabella di dati e controllarne le colonne. Le colonne da controllare e anche il numero di colonne da controllare sono noti solo in fase di esecuzione. I nomi delle colonne mi sono dati come array di stringhe e ogni colonna ha un elenco di stringhe da controllare. Ho provato degli alberi di espressione di esempio, come quello qui sotto.Il metodo statico richiede un'istanza nulla, il metodo non statico richiede un'istanza non null

Qui sto riscontrando un errore.

Il metodo statico richiede un'istanza null, il metodo non statico richiede un'istanza diversa da null. Nome parametro: esempio

alla linea

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

Gentilmente aiutatemi !!!

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 })); 

risposta

9

Significa la chiamata al metodo che si sta cercando di rappresentare è uno statico, ma si sta dando un'espressione bersaglio. Che è come cercare di chiamare:

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

Stai sorta di cercare di fare che in forma albero di espressione, che non è consentito neanche.

Sembra che questo sta accadendo per il metodo Field estensione sul DataRowExtensions - in modo che il "target" del metodo di estensione deve essere espresso come il primo argomento alla chiamata, perché in realtà desidera chiamare:

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

Così si vuole:

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

che chiamerà this overload che è il modo per chiamare un metodo statico con due argomenti.

+0

È possibile elaborare un po 'sopra? Perché passi le informazioni sul metodo come primo argomento al metodo Expression.Call qui? – Kobojunkie

+0

@Kobojunkie: Perché è così che dici a 'Expression.Call 'quale metodo statico ci interessa. Vedi http://msdn.microsoft.com/en-us/library/bb301084.aspx –

Problemi correlati