2015-11-17 15 views
6

Attualmente sto cercando di convertire unRimozione di una boxe non necessario convertire da ca # espressione

Expression<Func<T,object>> 

a un

Expression<Func<T,bool>> 

Attualmente l'orologio mi dimostra che la mia espressione detiene

Expression<Func<T,object>> myExpression = model=>Convert(model.IsAnAirplane) 

Mi piacerebbe semplificarlo a

Expression<Func<T,bool>> myExpression = model=>model.IsAnAirplane 

Attualmente mi riescono solo ad aggiungere un convertito, con conseguente:

Expression<Func<T,bool>> myExpression = model=>Convert(Convert(model.IsAnAirplane)) 

Ma dal momento che il tipo di fondo è un bool, dovrei essere in grado di graffiare i convertiti del tutto, giusto? Ho familiarità con i visitatori di espressioni, ecc, ma non riesco ancora a capire come rimuovere la conversione.

Modifica: questa risposta accettata a questa domanda Generic unboxing of Expression<Func<T, object>> to Expression<Func<T, TResult>> (che potrebbe essere un possibile duplicato) non funziona per me ... poiché l'espressione viene tradotta da EF, è possibile vederlo invece Converti (Convert()) semplicemente rimuovendo la prima conversione ..., questo risulta in "Impossibile eseguire il cast del tipo 'System.Boolean' per digitare 'System.Object'. LINQ to Entities supporta solo il casting di tipi primitivi o di enumerazione EDM."

risposta

4

Si dovrebbe essere in grado di togliere tutti Convert involucri con qualcosa di simile:

Expression<Func<YourModel, object>> boxed = m => m.IsAnAirplane; 

var unboxed = (Expression<Func<YourModel, bool>>)StripConvert(boxed); 

// ... 

public static LambdaExpression StripConvert<T>(Expression<Func<T, object>> source) 
{ 
    Expression result = source.Body; 
    // use a loop in case there are nested Convert expressions for some crazy reason 
    while (((result.NodeType == ExpressionType.Convert) 
       || (result.NodeType == ExpressionType.ConvertChecked)) 
      && (result.Type == typeof(object))) 
    { 
     result = ((UnaryExpression)result).Operand; 
    } 
    return Expression.Lambda(result, source.Parameters); 
} 

Se si preferisce, è possibile alterare StripConvert per tornare Expression<Func<T,U>> invece di una pianura LambdaExpression ed eseguire il cast all'interno del metodo stesso , ma in tal caso non saresti in grado di sfruttare il tipo di inferenza per la chiamata al metodo.

+0

Questo fa esattamente quello che volevo e funziona come un incantesimo, grazie! –

+0

Grazie, questo mi ha davvero salvato il sedere –

Problemi correlati