How to dynamically create an IQueryable <T> from a list of column names

I have 2 people, a country and a city. A country can have many cities. I want to achieve the following:

IQueryable<Country> query =
    myContext.Countries
             .Select(co => new Country
                 {
                     Id = co.Id,
                     Name = co.Name,
                     Cities = co.Cities.Select(c => new City { Id = c.Id, Name = c.Name })
                 })
             .AsQueryable();

But with a function that takes an array of property names such as

string[] columns = new string[] { "Id", "Name", "Cities.Name" }

So far, I have tried to change the following function on this platform, but it has thrown an exception for "Cities.Name" that does not belong to the Country object.

public static IQueryable<TResult> Select<TResult>(this IQueryable source, string[] columns)
{
    var sourceType = source.ElementType;
    var resultType = typeof(TResult);
    var parameter = Expression.Parameter(sourceType, "e");
    var bindings = columns.Select(column => Expression.Bind(resultType.GetProperty(column), Expression.PropertyOrField(parameter, column)));
    var body = Expression.MemberInit(Expression.New(resultType), bindings);
    var selector = Expression.Lambda(body, parameter);
    return source.Provider.CreateQuery<TResult>(
        Expression.Call(typeof(Queryable), "Select", new Type[] { sourceType, resultType },
            source.Expression, Expression.Quote(selector)));
}

Call:

IQueryable<Country> query = _hotelContext.Countries.Select<Country>(new string[] { "Id", "Name", "Cities.Name" });

return await query.ToListAsync();

Please help, I desperately need an answer. Hooray

+4
source share

Source: https://habr.com/ru/post/1695900/


All Articles