2015-11-17 13 views
6

ich zur Zeit versucht, eineeine nicht mehr benötigte Boxen aus aC# Ausdruck konvertieren Entfernen

Expression<Func<T,object>> 

zu einem

Expression<Func<T,bool>> 

Zeit die Uhr zeigt mir, dass mein Ausdruck

hält
Expression<Func<T,object>> myExpression = model=>Convert(model.IsAnAirplane) 
zu konvertieren

Ich möchte dies zu

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

Derzeit nur bei bekehrt Zugabe, was zu:

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

Aber da der zugrunde liegende Typ ein bool, sollte ich in der Lage, die Konvertiten ganz zu kratzen, nicht wahr? Ich kenne mich mit Expression-Besuchern usw. aus, kann aber immer noch nicht herausfinden, wie ich die Conversion entfernen kann.

Edit: diese akzeptierte Antwort auf diese Frage Generic unboxing of Expression<Func<T, object>> to Expression<Func<T, TResult>> (das könnte ein mögliches Duplikat sein) funktioniert nicht für mich ... wie der Ausdruck von EF übersetzt wird, können Sie sehen, es tut Convert (Convert()) statt Wenn nur die erste Konvertierung ... entfernt wird, führt dies dazu, dass der Typ "System.Boolean" nicht in den Typ "System.Object" umgewandelt werden kann. LINQ to Entities unterstützt nur das Generieren von EDM-Primitiven oder Aufzählungstypen. "

Antwort

4

Sie sollten in der Lage sein, um Streifen aus allen Convert Wrapper so etwas wie dies mit:

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

Wenn Sie möchten, können Sie StripConvert verändern Expression<Func<T,U>> anstelle einer einfachen LambdaExpression zurückzukehren und die Besetzung in der Methode selbst durchführen , aber in diesem Fall wären Sie nicht in der Lage, die Typ-Inferenzierung für den Methodenaufruf zu nutzen.

+0

Das tut genau das, was ich wollte, und funktioniert wie ein Charme, danke! –

+0

Danke, das hat mir wirklich den Hintern gerettet –