public IQueryable <object> ToObjectQuery(IQueryable <TResult> query) { IEnumerable <string> selectedPropertyNames = (Fields ?? "").ToLowerInvariant().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()); // Take properties from the mapped entitiy that match selected properties SelectedProperties = GetSelectableProperties <TResult>(selectedPropertyNames); selectedPropertyNames = SelectedProperties.Keys; // Construct runtime type by given property configuration ProxyType = ProxyGenerator.CreateClassProxy <TResult>().GetType(); // Create instance of source parameter ParameterExpression sourceParameter = Expression.Parameter(typeof(TResult), "t"); // Take fields from generated runtime type ProxyProperties = ProxyType.GetProperties(); // Elect selected fields if any. var propertyNames = selectedPropertyNames as string[] ?? selectedPropertyNames.ToArray(); if (propertyNames.Any()) { ProxyProperties = ProxyProperties.Where(pi => propertyNames.Any(p => pi.Name.ToLowerInvariant() == p)).ToArray(); } // Generate bindings from source type to runtime type IEnumerable <MemberBinding> bindingsToRuntimeType = ProxyProperties .Select(field => Expression.Bind( field, Expression.Property( sourceParameter, SelectedProperties[field.Name.ToLowerInvariant()] ) )); // Generate projection trom T to runtimeType and cast as IQueryable<object> IQueryable <object> runtimeTypeSelectExpressionQuery = ExpressionMapper.GenerateProjectedQuery <object>( typeof(TResult), ProxyType, bindingsToRuntimeType, query, sourceParameter ); return(runtimeTypeSelectExpressionQuery); }
public List <TResult> ToList(IQueryable <TResult> query) { IQueryable <object> runtimeTypeSelectExpressionQuery = ToObjectQuery(query); // Get result from database List <object> listOfObjects = runtimeTypeSelectExpressionQuery.ToList(); MethodInfo castMethod = typeof(Queryable) .GetMethod("Cast", BindingFlags.Public | BindingFlags.Static) .MakeGenericMethod(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(ProxyType, "p"); IDictionary <string, PropertyInfo> dynamicTypeFieldsDict = ProxyProperties.ToDictionary(f => f.Name.ToLowerInvariant(), f => f); // Generate bindings from runtime type to source type IEnumerable <MemberBinding> bindingsToTargetType = 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>( ProxyType, typeof(TResult), bindingsToTargetType, castedSource, runtimeParameter ); // Return list of T return(targetTypeSelectExpressionQuery.ToList()); }