1111using System . Reflection ;
1212using System . Runtime . CompilerServices ;
1313using Microsoft . AspNet . OData . Adapters ;
14+ using Microsoft . AspNet . OData . Builder ;
1415using Microsoft . AspNet . OData . Common ;
1516using Microsoft . AspNet . OData . Formatter ;
1617using Microsoft . AspNet . OData . Interfaces ;
@@ -633,15 +634,19 @@ public virtual Expression BindSingleComplexNode(SingleComplexNode singleComplexN
633634
634635 private Expression CreatePropertyAccessExpression ( Expression source , IEdmProperty property , string propertyPath = null )
635636 {
636- string propertyName = EdmLibHelpers . GetClrPropertyName ( property , Model ) ;
637+ PropertyDescriptor propertyDescriptor = EdmLibHelpers . GetClrPropertyDescriptor ( property , Model ) ;
638+ string propertyName = propertyDescriptor != null
639+ ? propertyDescriptor . MemberInfo . Name
640+ : EdmLibHelpers . GetClrPropertyName ( property , Model ) ;
637641 propertyPath = propertyPath ?? propertyName ;
638642
639643 if ( QuerySettings . HandleNullPropagation == HandleNullPropagationOption . True && IsNullable ( source . Type ) && source != _lambdaParameters [ ODataItParameterName ] )
640644 {
641645 var cleanSource = RemoveInnerNullPropagation ( source ) ;
642646 Expression propertyAccessExpression = null ;
643647
644- propertyAccessExpression = GetFlattenedPropertyExpression ( propertyPath ) ?? Expression . Property ( cleanSource , propertyName ) ;
648+ propertyAccessExpression = GetFlattenedPropertyExpression ( propertyPath )
649+ ?? CreatePropertyAccessExpression ( source , propertyName , propertyDescriptor ) ;
645650
646651 // source.property => source == null ? null : [CastToNullable]RemoveInnerNullPropagation(source).property
647652 // Notice that we are checking if source is null already. so we can safely remove any null checks when doing source.Property
@@ -655,10 +660,24 @@ private Expression CreatePropertyAccessExpression(Expression source, IEdmPropert
655660 }
656661 else
657662 {
658- return GetFlattenedPropertyExpression ( propertyPath ) ?? ConvertNonStandardPrimitives ( Expression . Property ( source , propertyName ) ) ;
663+ return GetFlattenedPropertyExpression ( propertyPath )
664+ ?? ConvertNonStandardPrimitives ( CreatePropertyAccessExpression ( source , propertyName , propertyDescriptor ) ) ;
659665 }
660666 }
661667
668+ private Expression CreatePropertyAccessExpression ( Expression source , string propertyName , PropertyDescriptor propertyDescriptor )
669+ {
670+ if ( propertyDescriptor != null )
671+ {
672+ if ( propertyDescriptor . MethodInfo != null )
673+ return Expression . Call ( null , propertyDescriptor . MethodInfo , source ) ;
674+ else
675+ return Expression . Property ( source , propertyDescriptor . PropertyInfo ) ;
676+ }
677+ else
678+ return Expression . Property ( source , propertyName ) ;
679+ }
680+
662681 /// <summary>
663682 /// Binds a <see cref="UnaryOperatorNode"/> to create a LINQ <see cref="Expression"/> that
664683 /// represents the semantics of the <see cref="UnaryOperatorNode"/>.
0 commit comments