Exemplo n.º 1
0
        public static async Task <List <TResult> > ToListAsync <TResult>(this FilteredExpressionQuery <TResult> filteredExpressionQuery, IQueryable <TResult> query) where TResult : class
        {
            IQueryable <object> runtimeTypeSelectExpressionQuery = filteredExpressionQuery.ToObjectQuery(query);

            // Get result from database
            List <object> listOfObjects = await runtimeTypeSelectExpressionQuery.ToListAsync();

            MethodInfo castMethod = typeof(Queryable)
                                    .GetMethod("Cast", BindingFlags.Public | BindingFlags.Static)
                                    .MakeGenericMethod(filteredExpressionQuery.ProxyType);

            // Cast list<objects> to IQueryable<runtimeType>
            IQueryable castedSource = castMethod.Invoke(
                null,
                new Object[] { listOfObjects.AsQueryable() }
                ) as IQueryable;

            // Create instance of runtime type parameter
            ParameterExpression runtimeParameter = Expression.Parameter(filteredExpressionQuery.ProxyType, "p");

            IDictionary <string, PropertyInfo> dynamicTypeFieldsDict =
                filteredExpressionQuery.ProxyProperties.ToDictionary(f => f.Name.ToLowerInvariant(), f => f);

            // Generate bindings from runtime type to source type
            IEnumerable <MemberBinding> bindingsToTargetType = filteredExpressionQuery.SelectedProperties.Values
                                                               .Select(property => Expression.Bind(
                                                                           property,
                                                                           Expression.Property(
                                                                               runtimeParameter,
                                                                               dynamicTypeFieldsDict[property.Name.ToLowerInvariant()]
                                                                               )
                                                                           ));

            // Generate projection trom runtimeType to T and cast as IQueryable<object>
            IQueryable <TResult> targetTypeSelectExpressionQuery
                = ExpressionMapper.GenerateProjectedQuery <TResult>(
                      filteredExpressionQuery.ProxyType,
                      typeof(TResult),
                      bindingsToTargetType,
                      castedSource,
                      runtimeParameter
                      );

            // Return list of T
            return(targetTypeSelectExpressionQuery.ToList());
        }