объединение нескольких выражений селектора LInq в одно выражение - PullRequest
1 голос
/ 08 мая 2019

Я нацеливаюсь на API, который принимает параметр, определенный следующим образом

Select(Expression<Func<User, object>> selectExpression);

Выражение используется для выбора одного или нескольких свойств, например, таких как

var expr = (u) => new { u.FirstName, u.LastName};

I 'Я хотел бы написать это selectExpression динамически, где я могу представить список имени свойства.Итак, что-то в этом роде

private static Expression<Func<User, object>> generateSelectExpression(List<string> propertiesToSelect)

Не то, чтобы речь шла не о EntityFramework или любом другом слое БД, а о чистой магии объектов.

1 Ответ

0 голосов
/ 10 мая 2019

Требуется некоторая магия динамики / отражения, но это должно сделать это

Отредактировано, чтобы разрешить обобщение, а не только класс пользователя

    static void Sample()
    {
        List<string> properties = new List<string>();
        properties.Add("FirstName");
        properties.Add("LastName");

        var exp = generateSelectExpression<User>(properties);
    }

    class User
    {
        public string FirstName;
        public string LastName;
    }

    private static Expression<Func<T, object>> generateSelectExpression<T>(List<string> propertiesToSelect)
    {
        Expression<Func<T, object>> exp = (x) => GetDynamicFromDictionary(GetProperties(x), propertiesToSelect);
        return exp;
    }

    private static dynamic GetDynamicFromDictionary(Dictionary<string,object> dict, List<string> propertiesToSelect)
    {
        var eo = new ExpandoObject();
        var eoColl = (ICollection<KeyValuePair<string, object>>)eo;

        foreach (var kvp in dict)
        {
            if (propertiesToSelect.Contains(kvp.Key))
            {
                eoColl.Add(kvp);
            }
        }

        dynamic eoDynamic = eo;

        return eoDynamic;
    }

    private static Dictionary<string, object> GetProperties(object obj)
    {
        var props = new Dictionary<string, object>();
        if (obj == null)
            return props;

        var type = obj.GetType();
        foreach (var prop in type.GetProperties())
        {
            var val = prop.GetValue(obj, new object[] { });
            props.Add(prop.Name, val);
        }

        return props;
    }
...