1

I am creating a procedure that performs a dynamic select of the fields. For example:

List<Company> items = await entity
    .Skip(model.Start)
    .Take(model.Length)
    .Select(GenerateDynamicSelect<Company>("Id,Name"))
    .ToListAsync();

Company Entity is:

public class Category
{
    public int Id { get; set; }
    public string? Name { get; set; }
    ...others 100 properties...
}

public class Company 
{
    public int Id { get; set; }
    public int? CategoryId { get; set; }
    public Category? Category { get; set; }
    public string? Code { get; set; }
    public string? Name { get; set; }
    ...others 100 properties...
}

everything works fine if I use

GenerateDynamicSelect<Company>("Id,Name")

But how do I use nested fields?

GenerateDynamicSelect<Company>("Id,Name,Category.Name")

It is important to avoid loading all the columns of the Category table.

The code i wrote:

private static Expression<Func<T, T>> GenerateDynamicSelect<T>(string fields)
{
    Type type = typeof(T);
    ParameterExpression parameter = Expression.Parameter(type, "x");
    NewExpression objToInitialise = Expression.New(type);
    HashSet<string> parsedColumns = new();

    BindingFlags searchFlags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance;
    IEnumerable<MemberAssignment> bindings = fields.Split(',')
        .Select(columnName => columnName.Trim().ToLower())
        .Where(columnName => !parsedColumns.Contains(columnName))
        .Select(columnName =>
            {
                parsedColumns.Add(columnName);
                PropertyInfo? property;
                if (columnName.Contains('.'))
                {
                    string[] parts = columnName.Split('.');
                    property = type.GetProperty(parts[0], searchFlags);

                    how i can do?
                }
                else
                {
                    property = type.GetProperty(columnName, searchFlags);
                }
                MemberExpression originalValue = Expression.Property(parameter, property);
                return Expression.Bind(property, originalValue);
            }
        );
    MemberInitExpression initializedMember = Expression.MemberInit(objToInitialise, bindings);
    return Expression.Lambda<Func<T, T>>(initializedMember, parameter);
}

Thanks. I use .NET 6

Svyatoslav Danyliv
  • 21,911
  • 3
  • 16
  • 32
  • I think this function should do that for you, check this [answer](https://stackoverflow.com/a/66334073/10646316) – Svyatoslav Danyliv Apr 28 '22 at 16:59
  • I finally solved it with the help of this post: https://stackoverflow.com/questions/53500412/write-dynamic-linq-queries-for-sorting-and-projecting-with-ef-core. Thank you all – FireSoft Italia Apr 29 '22 at 06:30

0 Answers0