@forced

Как усовершенствовать extension-метод для IQueryable?

Всем привет!
Есть для автомаппера библиотека, позволяющая работать с OData. Суть ее в том, что она сама прописывает инклуды, фильтры и прочее через переданный в синтаксисе OData запрос.

В моей системе есть роли, и один и тот же метод используется для получения разного объема информации.
Собственно вся задача в том, что я хочу вешать на объекты кастомные атрибуты, например - [NotMapWhenNotInRole(Role.User)] и после чего позволять в Selectотносить только те свойства, которые разрешены атрибутом

Я методом дебага и рантайма выловил нужные мне типы выражений, но вот самая ключевая проблема их модифицировать. Метод-то я написал, но выглядит он крайне ненадежно и колхозно.
С expression trees я только знакомлюсь, эта задача одна из типовых (которые буду применять лично я)

А вот собственно метод
public static IQueryable<T> ODataMapFromRoles<T>(this IQueryable<T> query, List<Role> roles)
    {
        var dt1 = query.Expression as MethodCallExpression;
        var dt2 = dt1!.Arguments.OfType<UnaryExpression>().First();
        var dt3 = dt2.Operand as LambdaExpression;
       // Задача решилась бы очень просто если для переменной dt4 можно было выставить параметр Bindings. Однако он readonly!
        var dt4 = dt3!.Body as MemberInitExpression;
       

        return query.Provider.CreateQuery<T>(Expression.Call(dt1.Method ,dt1.Arguments.OfType<EntityQueryRootExpression>().First(),
            Expression.MakeUnary(dt2.NodeType, Expression.Lambda(Expression.MemberInit(dt4.NewExpression, new List<MemberBinding>()), dt3.Parameters), dt2.Type, dt2.Method)));
        
        return query;
    }


Используется примерно так
return await _dbContext.Accounts.GetQuery(_mapper, query).ODataMapFromRoles(_authStorage.CurrentRoles).ToListAsync(token);


По большей части вопрос в том, как это сделать грамотно? Селект может быть вполне себе вложенный, а значит и глубина вложенности экспрешена может быть бесконечной -
не доставать ж мне каждый экспрешен и опрокидывать его
  • Вопрос задан
  • 110 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы