private static void AssertTransformation( Expression <Func <TestClass, bool> > input, Expression <Func <TestClass, bool> > output) { var visitor = new BooleanOptimizingExpressionVisitor(); var result = visitor.Visit(input.Body); var hasher = new HashingExpressionVisitor(); hasher.Visit(result); var inputHash = hasher.HashCode; hasher.Reset(); hasher.Visit(output.Body); var outputHash = hasher.HashCode; Assert.AreEqual(inputHash, outputHash, "Output expression trees do not match"); }
private static void AssertTransformation <TResult>( Expression <Func <IQueryable <MyClass1>, TResult> > input, Expression <Func <IQueryable <MyClass1>, TResult> > output) { var visitor = new SelectorPushdownExpressionVisitor(); var result = visitor.Visit(input.Body); var hasher = new HashingExpressionVisitor(); hasher.Visit(result); var inputHash = hasher.HashCode; hasher.Reset(); hasher.Visit(output.Body); var outputHash = hasher.HashCode; Assert.AreEqual(inputHash, outputHash, "Output expression trees do not match"); }
public void Hashing() { var hasher = new HashingExpressionVisitor(); // No closure Expression <Func <string> > expr1 = () => "hello".ToString().Substring(0, 1); Expression <Func <string> > expr2 = () => "hello".ToString().Substring(0, 1); hasher.Visit(expr1); var hashCode1 = hasher.HashCode; hasher.Reset(); hasher.Visit(expr2); var hashCode2 = hasher.HashCode; hasher.Reset(); Assert.AreNotEqual(expr1, expr2); Assert.AreEqual(hashCode1, hashCode2); // Closure Expression <Func <string> > CreateExpressionWithClosure(int value) { Expression <Func <string> > expression = () => "hello".ToString().Substring(value, 1); return(expression); } var expr3 = CreateExpressionWithClosure(0); var expr4 = CreateExpressionWithClosure(1); hasher.Visit(expr3); var hashCode3 = hasher.HashCode; hasher.Reset(); hasher.Visit(expr4); var hashCode4 = hasher.HashCode; hasher.Reset(); Assert.AreNotEqual(expr3, expr4); Assert.AreEqual(hashCode3, hashCode4); // Partially evaluated var evaluator = new PartialEvaluatingExpressionVisitor(); Expression <Func <string> > expr5 = () => "hello".ToString().Substring(0, 1); var expr6 = CreateExpressionWithClosure(0); hasher.Visit(evaluator.Visit(expr5)); var hashCode5 = hasher.HashCode; hasher.Reset(); hasher.Visit(evaluator.Visit(expr6)); var hashCode6 = hasher.HashCode; hasher.Reset(); Assert.AreNotEqual(expr5, expr6); Assert.AreEqual(hashCode5, hashCode6); }
private static void AssertTransformation <TResult>( Expression <Func <IQueryable <MyClass1>, TResult> > input, Expression <Func <IQueryable <MyClass1>, TResult> > output) { var myClass1KeyParameter = Expression.Parameter(typeof(MyClass1), "m1"); var myClass1KeyDescriptor = new PrimaryKeyDescriptor { TargetType = typeof(MyClass1), KeySelector = Expression.Lambda( Expression.MakeMemberAccess( myClass1KeyParameter, typeof(MyClass1).GetRuntimeProperty(nameof(MyClass1.Id))), myClass1KeyParameter) }; var myClass2KeyParameter = Expression.Parameter(typeof(MyClass2), "m2"); var myClass2KeyDescriptor = new PrimaryKeyDescriptor { TargetType = typeof(MyClass2), KeySelector = Expression.Lambda( Expression.MakeMemberAccess( myClass2KeyParameter, typeof(MyClass2).GetRuntimeProperty(nameof(MyClass2.Id))), myClass2KeyParameter) }; var myClass1NavigationDescriptor = new NavigationDescriptor { Type = typeof(MyClass1), Member = typeof(MyClass1).GetRuntimeProperty(nameof(MyClass1.Nav1)), OuterKeySelector = Expression.Lambda( Expression.MakeMemberAccess( myClass1KeyParameter, typeof(MyClass1).GetRuntimeProperty(nameof(MyClass1.Nav1Id))), myClass1KeyParameter), InnerKeySelector = myClass2KeyDescriptor.KeySelector, }; var visitor = new KeyEqualityRewritingExpressionVisitor( primaryKeyDescriptors: new[] { myClass1KeyDescriptor, myClass2KeyDescriptor, }, navigationDescriptors: new[] { myClass1NavigationDescriptor, }); var result = visitor.Visit(input.Body); var hasher = new HashingExpressionVisitor(); hasher.Visit(result); var inputHash = hasher.HashCode; hasher.Reset(); hasher.Visit(output.Body); var outputHash = hasher.HashCode; Assert.AreEqual(inputHash, outputHash, "Output expression trees do not match"); }