Как выбрать значение в запросе LINQ в зависимости от результата выражения?

Я использую EF6 и ищу решение для создания запроса, который должен выбирать одно из полей в зависимости от значения, возвращаемого Expression. Я играю с библиотекой LINQKit для этого, но с этим не получается.

Поэтому я создал повторно используемый предикат, который вычисляет логику в БД:

public partial class Study
{
    public static Expression<Func<Study, bool>> ShouldNameBeDisplayedForStaffExpression(int staffId)
    {
        return study =>
            (study.StudyViewAccessId == 1 && study.StudyEditAccessId == 1)
            || study.Roles.Any(y => y.StaffId == staffId);
        //Here other additional logic
    }
}

И теперь мне нужно установить правильное значение поля Name в зависимости от результата, который возвращает предикат. Основное требование - это должно быть сделано на уровне запроса (в коллекции IQueryable). StudiesCoreModelsQuery — это наборы сущностей EF6.

IQueryable<Study> studiesCoreModelsQuery = this._dbContext.Studies;
IQueryable<StudyViewModel> query = studiesCoreModelsQuery.AsExpandable().Select(x => new StudyViewModel
{
    Name = Study.ShouldNameBeDisplayedForStaffExpression(staffId).Invoke(x)
        ? x.Name
        : "Hidden"
});

Не могу понять, как получить результат выполнения Expression в Select. Я буду признателен за любую помощь.


person Ruslan Borovok    schedule 21.01.2020    source источник
comment
Откуда staffId? Можете ли вы переместить Study.ShouldNameBeDisplayedForStaffExpression(staffId) вызов за пределы Select? Потому что там, где он сейчас, он толком не называется. например var showNameExpr = Study.ShouldNameBeDisplayedForStaffExpression(staffId); и затем внутри Select сделать Name = showNameExpr.Invoke(x) ? x.Name : "Hidden"   -  person Ivan Stoev    schedule 21.01.2020
comment
@IvanStoev Основная идея — получить возможность повторно использовать логику из выражения ShouldNameBeDisplayedForStaffExpression в других запросах. Эта логика не может быть выполнена вне запроса, поскольку она является частью запроса и должна применяться к каждому элементу на основе значений в БД. StaffId – это переменная, определенная над запросом. Она может быть любым целым числом.   -  person Ruslan Borovok    schedule 21.01.2020
comment
Вот что я говорю. Получите выражение вне запроса и Invoke внутри.   -  person Ivan Stoev    schedule 21.01.2020


Ответы (1)


@Ivan Stoev, вы правы. Ваше предложение решило проблему. Рабочий код следующий:

IQueryable<Study> studiesCoreModelsQuery = this._dbContext.Studies;
var expression = Study.ShouldNameBeDisplayedForStaffExpression(staffId);
IQueryable<StudyViewModel> query = studiesCoreModelsQuery.AsExpandable().Select(x => new StudyViewModel
{
    Name = expression.Invoke(x)
        ? x.Name
        : "Hidden"
});
person Ruslan Borovok    schedule 22.01.2020