public void MemberInitExpressionForDerivedTypeCanBeUsedWithPropertyTypedAsBaseType() { Expression <Func <Cook, Result <BaseValue> > > lambaExpression = c => new Result <BaseValue> { Value = new DerivedValue { StringValue = c.FirstName } }; // new Result { ... } var resultInitExpression = ((MemberInitExpression)lambaExpression.Body); // BaseValue = new DerivedValue { ... } var derivedValueMemberAssignment = ((MemberAssignment)resultInitExpression.Bindings[0]); // new DerivedValue { ... } var derivedValueInitExpression = (MemberInitExpression)(derivedValueMemberAssignment.Expression); // StringValue = c.FirstName var derivedValueStringValueMemberAssignment = ((MemberAssignment)derivedValueInitExpression.Bindings[0]); // c.FirstName var derivedValueStringValuePropertyExpression = (MemberExpression)derivedValueStringValueMemberAssignment.Expression; var inputParameter = Expression.Parameter(typeof(Result <BaseValue>), "input"); var result = AccessorFindingExpressionVisitor.FindAccessorLambda( searchedExpression: derivedValueStringValuePropertyExpression, fullExpression: resultInitExpression, inputParameter: inputParameter); Expression <Func <Result <BaseValue>, string> > expectedResult = input => ((DerivedValue)input.Value).StringValue; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void NewExpressionForAnonymousType() { Expression <Func <Cook, dynamic> > lambaExpression = c => new { OuterValue = new { InnerValue = c.FirstName } }; // new OuterType (...) var resultInitExpression = ((NewExpression)lambaExpression.Body); // new InnerType (...) var derivedValueInitExpression = (NewExpression)resultInitExpression.Arguments[0]; // c.FirstName var derivedValueStringValuePropertyExpression = (MemberExpression)derivedValueInitExpression.Arguments[0]; var inputParameter = Expression.Parameter(resultInitExpression.Type, "input"); var result = AccessorFindingExpressionVisitor.FindAccessorLambda( searchedExpression: derivedValueStringValuePropertyExpression, fullExpression: resultInitExpression, inputParameter: inputParameter); // Expression<Func<dynamic, string>> input => input.OuterValue.InnerValue; var expectedParameter = Expression.Parameter(resultInitExpression.Type, "input"); #if !NET_3_5 var expectedOuterProperty = Expression.Property(expectedParameter, "OuterValue"); var expectedInnerProperty = Expression.Property(expectedOuterProperty, "InnerValue"); var expectedResult = Expression.Lambda(expectedInnerProperty, expectedParameter); #else var expectedOuterGetter = Expression.Call(expectedParameter, "get_OuterValue", new Type[0]); var expectedInnerGetter = Expression.Call(expectedOuterGetter, "get_InnerValue", new Type[0]); var expectedResult = Expression.Lambda(expectedInnerGetter, expectedParameter); #endif ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
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"); #if !NET_3_5 var outerAnonymousTypeBProperty = typeof(AnonymousType <int, AnonymousType>).GetProperty("b"); #endif // 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 = AccessorFindingExpressionVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _nestedInputParameter); var inputParameter = Expression.Parameter(typeof(AnonymousType <int, AnonymousType>), "input"); // input => input.get_b().get_a() var expectedResult = Expression.Lambda( #if !NET_3_5 Expression.MakeMemberAccess(Expression.MakeMemberAccess(inputParameter, outerAnonymousTypeBProperty), _anonymousTypeAProperty), #else Expression.Call(Expression.Call(inputParameter, outerAnonymousTypeBGetter), _anonymousTypeAGetter), #endif inputParameter); ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void TrivialExpression() { var result = AccessorFindingExpressionVisitor.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))); AccessorFindingExpressionVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); }
public void ConvertExpression() { var parameter = Expression.Parameter(typeof(long), "input"); var fullExpression = Expression.Convert(_searchedExpression, typeof(long)); var result = AccessorFindingExpressionVisitor.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 = AccessorFindingExpressionVisitor.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))); AccessorFindingExpressionVisitor.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 = AccessorFindingExpressionVisitor.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 <EntityTrackingInfo> entityTrackingInfos, Expression selector) => (from entityTrackingInfo in entityTrackingInfos select (Func <TResult, object>) AccessorFindingExpressionVisitor .FindAccessorLambda( entityTrackingInfo.QuerySourceReferenceExpression, selector, Expression.Parameter(typeof(TResult), "result")) .Compile()) .ToList();
protected virtual void IncludeNavigations( [NotNull] QueryModel queryModel, [NotNull] IReadOnlyCollection <IncludeSpecification> includeSpecifications) { Check.NotNull(queryModel, nameof(queryModel)); Check.NotNull(includeSpecifications, nameof(includeSpecifications)); var querySourceTracingExpressionVisitor = new QuerySourceTracingExpressionVisitor(); foreach (var includeSpecification in includeSpecifications) { var resultQuerySourceReferenceExpression = querySourceTracingExpressionVisitor .FindResultQuerySourceReferenceExpression( queryModel.SelectClause.Selector, includeSpecification.QuerySource); if (resultQuerySourceReferenceExpression != null) { var accessorLambda = AccessorFindingExpressionVisitor .FindAccessorLambda( resultQuerySourceReferenceExpression, queryModel.SelectClause.Selector, Expression.Parameter(queryModel.SelectClause.Selector.Type)); QueryCompilationContext.Logger .LogInformation( includeSpecification.NavigationPath.Join("."), Strings.LogIncludingNavigation); IncludeNavigations( includeSpecification, _expression.Type.GetSequenceType(), accessorLambda, QuerySourceRequiresTracking(includeSpecification.QuerySource)); QueryCompilationContext .AddTrackableInclude( resultQuerySourceReferenceExpression.ReferencedQuerySource, includeSpecification.NavigationPath); } } }
protected virtual void IncludeNavigations( [NotNull] QueryModel queryModel, [NotNull] IReadOnlyCollection <IncludeSpecification> includeSpecifications) { Check.NotNull(queryModel, nameof(queryModel)); Check.NotNull(includeSpecifications, nameof(includeSpecifications)); foreach (var includeSpecification in includeSpecifications) { var resultQuerySourceReferenceExpression = _querySourceTracingExpressionVisitorFactory .Create() .FindResultQuerySourceReferenceExpression( queryModel.SelectClause.Selector, includeSpecification.QuerySource); if (resultQuerySourceReferenceExpression != null) { var accessorLambda = AccessorFindingExpressionVisitor .FindAccessorLambda( resultQuerySourceReferenceExpression, queryModel.SelectClause.Selector, Expression.Parameter(queryModel.SelectClause.Selector.Type, "result")); QueryCompilationContext.Logger .LogVerbose( CoreLoggingEventId.IncludingNavigation, () => CoreStrings.LogIncludingNavigation(includeSpecification.NavigationPath.Join("."))); IncludeNavigations( includeSpecification, _expression.Type.GetSequenceType(), accessorLambda, QueryCompilationContext.IsTrackingQuery); QueryCompilationContext .AddTrackableInclude( resultQuerySourceReferenceExpression.ReferencedQuerySource, includeSpecification.NavigationPath); } } }
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 = AccessorFindingExpressionVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); var inputParameter = Expression.Parameter(typeof(AnonymousType), "input"); var expectedResult = Expression.Lambda( #if !NET_3_5 Expression.MakeMemberAccess(inputParameter, _anonymousTypeAProperty), #else Expression.Call(inputParameter, _anonymousTypeAGetter), #endif inputParameter); ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
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 = AccessorFindingExpressionVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _nestedInputParameter); Expression <Func <AnonymousType <int, AnonymousType>, int> > expectedResult = input => input.b.a; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void NestedMemberBindingExpressionWithDerivedType() { var outerTypeCtor = typeof(Result <BaseValue>).GetConstructor(Type.EmptyTypes); var outerTypeValueProperty = typeof(Result <BaseValue>).GetProperty("Value"); var innerTypeCtor = typeof(DerivedValue).GetConstructor(Type.EmptyTypes); var innerTypeStringValueProperty = typeof(DerivedValue).GetProperty("StringValue"); var searchedExpression = Expression.Constant("a"); var nestedInputParameter = Expression.Parameter(typeof(Result <BaseValue>), "input"); // new Result<BaseValue>() { Value = new DerivedValue() { StringValue = _searchedExpression } } var innerExpression = Expression.MemberInit( Expression.New(innerTypeCtor), Expression.Bind(innerTypeStringValueProperty, searchedExpression)); var fullExpression = Expression.MemberInit( Expression.New(outerTypeCtor), Expression.Bind(outerTypeValueProperty, innerExpression)); var result = AccessorFindingExpressionVisitor.FindAccessorLambda(searchedExpression, fullExpression, nestedInputParameter); Expression <Func <Result <BaseValue>, string> > expectedResult = input => ((DerivedValue)input.Value).StringValue; ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result); }
public void SearchedExpressionNotFound_AlthoughInUnaryPlusExpression() { var fullExpression = Expression.UnaryPlus(_searchedExpression); AccessorFindingExpressionVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _intInputParameter); }
public void SearchedExpressionNotFound_AlthoughInNewExpressionWithoutMember() { var fullExpression = Expression.New(_anonymousTypeCtorWithArgs, _searchedExpression, _searchedExpression); AccessorFindingExpressionVisitor.FindAccessorLambda(_searchedExpression, fullExpression, _simpleInputParameter); }