private static Func <TIn, TOut> CompileFromFingerprint(Expression <Func <TIn, TOut> > expr) { List <object> capturedConstants; ExpressionFingerprintChain fingerprint = FingerprintingExpressionVisitor.GetFingerprintChain(expr, out capturedConstants); if (fingerprint != null) { var del = _fingerprintedCache.GetOrAdd(fingerprint, _ => { // Fingerprinting succeeded, but there was a cache miss. Rewrite the expression // and add the rewritten expression to the cache. var hoistedExpr = HoistingExpressionVisitor <TIn, TOut> .Hoist(expr); return(hoistedExpr.Compile()); }); return(model => del(model, capturedConstants)); } // couldn't be fingerprinted return(null); }
// Returns the fingerprint chain + captured constants list for this expression, or null // if the expression couldn't be fingerprinted. public static ExpressionFingerprintChain GetFingerprintChain( Expression expr, out List <object> capturedConstants ) { FingerprintingExpressionVisitor visitor = new FingerprintingExpressionVisitor(); visitor.Visit(expr); if (visitor._gaveUp) { capturedConstants = null; return(null); } else { capturedConstants = visitor._seenConstants; return(visitor._currentChain); } }