public void NestedNewExpression() { var outerAnonymousTypeCtor = typeof(AnonymousType <int, AnonymousType>).GetConstructor(new[] { typeof(int), typeof(AnonymousType) }); var outerAnonymousTypeAGetter = typeof(AnonymousType <int, AnonymousType>).GetMethod("get_a"); var outerAnonymousTypeBGetter = typeof(AnonymousType <int, AnonymousType>).GetMethod("get_b"); var outerAnonymousTypeBProperty = typeof(AnonymousType <int, AnonymousType>).GetProperty("b"); // new AnonymousType (get_a = 2, get_b = new AnonymousType (get_a = _searchedExpression, get_b = 1)) var innerExpression = Expression.New( _anonymousTypeCtorWithArgs, new[] { _searchedExpression, Expression.Constant(1) }, _anonymousTypeAGetter, _anonymousTypeBGetter); var fullExpression = Expression.New( outerAnonymousTypeCtor, new Expression[] { Expression.Constant(2), innerExpression }, outerAnonymousTypeAGetter, outerAnonymousTypeBGetter); var result = AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _nestedInputParameter); var inputParameter = Expression.Parameter(typeof(AnonymousType <int, AnonymousType>), "input"); var expectedResult = Expression.Lambda( Expression.MakeMemberAccess(Expression.MakeMemberAccess(inputParameter, outerAnonymousTypeBProperty), _anonymousTypeAProperty), inputParameter); // input => input.get_b().get_a() ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void TrivialExpression() { var result = AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, _searchedExpression, _intInputParameter); Expression <Func <int, int> > expectedResult = input => input; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void SearchedExpressionNotFound_AlthoughInOtherExpression() { var fullExpression = Expression.MemberInit( Expression.New(_anonymousTypeCtorWithoutArgs), Expression.Bind(_anonymousTypeAProperty, Expression.MakeBinary(ExpressionType.Add, _searchedExpression, _searchedExpression)), Expression.Bind(_anonymousTypeBProperty, Expression.Constant(1))); AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); }
public void ConvertExpression() { var parameter = Expression.Parameter(typeof(long), "input"); var fullExpression = Expression.Convert(_searchedExpression, typeof(long)); var result = AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, parameter); Expression <Func <long, int> > expectedResult = input => (int)input; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void TrivialExpression_WithEqualsTrue_ButNotReferenceEquals() { var searchedExpression1 = new QuerySourceReferenceExpression(ExpressionHelper.CreateMainFromClause <Cook>()); var searchedExpression2 = new QuerySourceReferenceExpression(searchedExpression1.ReferencedQuerySource); var inputParameter = Expression.Parameter(typeof(Cook), "input"); var result = AccessorFindingExpressionTreeVisitor.FindAccessorLambda(searchedExpression1, searchedExpression2, inputParameter); Expression <Func <Cook, Cook> > expectedResult = input => input; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void SearchedExpressionNotFound_AlthoughInOtherMemberBinding() { var anonymousTypeListProperty = typeof(AnonymousType).GetProperty("List"); var listAddMethod = typeof(List <int>).GetMethod("Add"); var fullExpression = Expression.MemberInit( Expression.New(_anonymousTypeCtorWithoutArgs), Expression.ListBind(anonymousTypeListProperty, Expression.ElementInit(listAddMethod, _searchedExpression)), Expression.Bind(_anonymousTypeBProperty, Expression.Constant(1))); AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); }
public void SimpleMemberBindingExpression() { // new AnonymousType() { a = _searchedExpression, b = 1 } var fullExpression = Expression.MemberInit( Expression.New(_anonymousTypeCtorWithoutArgs), Expression.Bind(_anonymousTypeAProperty, _searchedExpression), Expression.Bind(_anonymousTypeBProperty, Expression.Constant(1))); var result = AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); Expression <Func <AnonymousType, int> > expectedResult = input => input.a; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
private static ICollection <Func <TResult, object> > GetEntityAccessors <TResult>( IEnumerable <QuerySourceReferenceExpression> querySourceReferenceExpressions, Expression selector) { return ((from qsre in querySourceReferenceExpressions select (Func <TResult, object>) AccessorFindingExpressionTreeVisitor .FindAccessorLambda( qsre, selector, Expression.Parameter(typeof(TResult))) .Compile() ) .ToList()); }
public void SimpleNewExpression() { // new AnonymousType (get_a = _searchedExpression, get_b = 1) var fullExpression = Expression.New( _anonymousTypeCtorWithArgs, new[] { _searchedExpression, Expression.Constant(1) }, _anonymousTypeAGetter, _anonymousTypeBGetter); var result = AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); var inputParameter = Expression.Parameter(typeof(AnonymousType), "input"); var expectedResult = Expression.Lambda( Expression.MakeMemberAccess(inputParameter, _anonymousTypeAProperty), inputParameter); ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
private static ICollection <Func <TResult, object> > GetEntityAccessors <TResult>( IEnumerable <EntityTrackingInfo> entityTrackingInfos, Expression selector) { return ((from entityTrackingInfo in entityTrackingInfos select (Func <TResult, object>) AccessorFindingExpressionTreeVisitor .FindAccessorLambda( entityTrackingInfo.QuerySourceReferenceExpression, selector, Expression.Parameter(typeof(TResult))) .Compile() ) .ToList()); }
public void NestedMemberBindingExpression() { var outerAnonymousTypeCtor = typeof(AnonymousType <int, AnonymousType>).GetConstructor(Type.EmptyTypes); var outerAnonymousTypeAProperty = typeof(AnonymousType <int, AnonymousType>).GetProperty("a"); var outerAnonymousTypeBProperty = typeof(AnonymousType <int, AnonymousType>).GetProperty("b"); // new AnonymousType() { a = 2, b = new AnonymousType() { a = _searchedExpression, b = 1 } } var innerExpression = Expression.MemberInit( Expression.New(_anonymousTypeCtorWithoutArgs), Expression.Bind(_anonymousTypeAProperty, _searchedExpression), Expression.Bind(_anonymousTypeBProperty, Expression.Constant(1))); var fullExpression = Expression.MemberInit( Expression.New(outerAnonymousTypeCtor), Expression.Bind(outerAnonymousTypeAProperty, Expression.Constant(2)), Expression.Bind(outerAnonymousTypeBProperty, innerExpression)); var result = AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _nestedInputParameter); Expression <Func <AnonymousType <int, AnonymousType>, int> > expectedResult = input => input.b.a; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
protected virtual void IncludeNavigations( [NotNull] QueryModel queryModel, [NotNull] Type resultType) { Check.NotNull(queryModel, "queryModel"); Check.NotNull(resultType, "resultType"); var querySourceTracingExpressionTreeVisitor = new QuerySourceTracingExpressionTreeVisitor(); foreach (var include in from queryAnnotation in _queryAnnotations let includeResultOperator = queryAnnotation.ResultOperator as IncludeResultOperator where includeResultOperator != null let navigationPath = BindNavigationPathMemberExpression( (MemberExpression)includeResultOperator.NavigationPropertyPath, (ns, _) => BindChainedNavigations(ns, includeResultOperator.ChainedNavigationProperties).ToArray()) orderby navigationPath != null && navigationPath.First().PointsToPrincipal select new { navigationPath, queryAnnotation.QuerySource, includeResultOperator.NavigationPropertyPath }) { if (include.navigationPath != null) { var resultQuerySourceReferenceExpression = querySourceTracingExpressionTreeVisitor .FindResultQuerySourceReferenceExpression( queryModel.SelectClause.Selector, include.QuerySource); if (resultQuerySourceReferenceExpression != null) { var accessorLambda = AccessorFindingExpressionTreeVisitor .FindAccessorLambda( resultQuerySourceReferenceExpression, queryModel.SelectClause.Selector, Expression.Parameter(queryModel.SelectClause.Selector.Type)); QueryCompilationContext.Logger .WriteInformation( include.navigationPath.Join("."), Strings.LogIncludingNavigation); IncludeNavigations( include.QuerySource, resultType, accessorLambda, include.navigationPath); } } else { throw new InvalidOperationException( Strings.IncludeNonBindableExpression(include.NavigationPropertyPath)); } } }
public void SearchedExpressionNotFound_AlthoughInUnaryPlusExpression() { var fullExpression = Expression.UnaryPlus(_searchedExpression); AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _intInputParameter); }
public void SearchedExpressionNotFound_AlthoughInNewExpressionWithoutMember() { var fullExpression = Expression.New(_anonymousTypeCtorWithArgs, _searchedExpression, _searchedExpression); AccessorFindingExpressionTreeVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); }
protected virtual void IncludeNavigations([NotNull] QueryModel queryModel) { Check.NotNull(queryModel, nameof(queryModel)); var includeSpecifications = QueryCompilationContext.QueryAnnotations .OfType <IncludeQueryAnnotation>() .Select(annotation => { var navigationPath = BindNavigationPathMemberExpression( (MemberExpression)annotation.NavigationPropertyPath, (ns, _) => BindChainedNavigations(ns, annotation.ChainedNavigationProperties).ToArray()); if (navigationPath == null) { throw new InvalidOperationException( Strings.IncludeNonBindableExpression(annotation.NavigationPropertyPath)); } return(new IncludeSpecification(annotation.QuerySource, navigationPath)); }) .ToList(); var querySourceTracingExpressionTreeVisitor = new QuerySourceTracingExpressionTreeVisitor(); foreach (var includeSpecification in includeSpecifications .OrderBy(a => a.NavigationPath.First().PointsToPrincipal())) { var resultQuerySourceReferenceExpression = querySourceTracingExpressionTreeVisitor .FindResultQuerySourceReferenceExpression( queryModel.SelectClause.Selector, includeSpecification.QuerySource); if (resultQuerySourceReferenceExpression != null) { var accessorLambda = AccessorFindingExpressionTreeVisitor .FindAccessorLambda( resultQuerySourceReferenceExpression, queryModel.SelectClause.Selector, Expression.Parameter(queryModel.SelectClause.Selector.Type)); QueryCompilationContext.Logger .LogInformation( includeSpecification.NavigationPath.Join("."), Strings.LogIncludingNavigation); IncludeNavigations( includeSpecification.QuerySource, _expression.Type.GetSequenceType(), accessorLambda, includeSpecification.NavigationPath, QuerySourceRequiresTracking(includeSpecification.QuerySource)); QueryCompilationContext .AddTrackableInclude( resultQuerySourceReferenceExpression.ReferencedQuerySource, includeSpecification.NavigationPath); } } }
protected virtual void IncludeNavigations( [NotNull] QueryModel queryModel, [NotNull] Type resultType, [NotNull] ICollection <QueryAnnotation> queryAnnotations) { Check.NotNull(queryModel, "queryModel"); Check.NotNull(resultType, "resultType"); Check.NotNull(queryAnnotations, "queryAnnotations"); var querySourceTracingExpressionTreeVisitor = new QuerySourceTracingExpressionTreeVisitor(); foreach (var queryAnnotation in queryAnnotations) { var includeResultOperator = queryAnnotation.ResultOperator as IncludeResultOperator; if (includeResultOperator != null) { var navigation = BindNavigationMemberExpression( (MemberExpression)includeResultOperator.NavigationPropertyPath, (n, _) => n); if (navigation != null) { var resultQuerySourceReferenceExpression = querySourceTracingExpressionTreeVisitor .FindResultQuerySourceReferenceExpression( queryModel.SelectClause.Selector, queryAnnotation.QuerySource); if (resultQuerySourceReferenceExpression != null) { var accessorLambda = AccessorFindingExpressionTreeVisitor .FindAccessorLambda( resultQuerySourceReferenceExpression, queryModel.SelectClause.Selector, Expression.Parameter(queryModel.SelectClause.Selector.Type)); QueryCompilationContext.Logger .WriteInformation( navigation, Strings.FormatLogIncludingNavigation); IncludeNavigation( queryAnnotation.QuerySource, resultType, accessorLambda, navigation); } } else { throw new NotImplementedException( Strings.FormatIncludeNonBindableExpression(includeResultOperator.NavigationPropertyPath)); } } } }