Мне не удалось найти примеры, в которых вы можете условно исключить поля на основе переменной в проекции выбора в LINQ, см. также LINQ: выберите объект и измените некоторые свойства без создания нового объекта.
Позвольте мне немного рассказать о том, чего я пытаюсь достичь. Я хочу ограничить некоторые поля в DTO, устанавливаемые из модели, в зависимости от того, может ли пользователь редактировать данные (например, поле комментария). Например, следующий выбор с делегатом с именем CustomerView.
var qry = _ctx.Customer.Select(CustomerView(User.IsInRole("Editor")));
Модель Customer имеет свойство навигации Orders, и следующая функция преобразует данные в объект DTO CusomerViewModel.
private Expression<Func<Customer, CustomerViewModel>> CustomerView(bool isEditor) {
return c => new CustomerViewModel
{
Id = c.Id,
Name = c.Name,
Comment = isEditor ? c.Comment : null,
OrderCount = c.Orders.Count()
};
}
Это сгенерирует SQL, например CASE WHEN @__isEditor_0 = TRUE THEN Comment ELSE NULL
, который работает, но я бы предпочел, чтобы выражение даже не генерировалось, т.е. поле оставалось по умолчанию. Это простой вариант использования, но если бы я хотел сделать то же самое с полем OrderCount, подзапрос SQL все равно был бы включен.
Конечно, я мог бы создать другую функцию для пользователей, не являющихся редакторами, которая исключает определенные поля, но я бы предпочел не поддерживать отдельные проекции, особенно когда они более сложные.
Я вижу вопросы, в которых динамический LINQ используется для предложений where, но не так много для выбора. Возможен ли такой подход?
Изменить: можно ли вручную удалить поля из дерева выражений после использования выбора, возможно, с помощью метода расширения?
_ctx.Customer.Select(CustomerView(User.IsInRole("Editor"))) .Select(c => new { c.Id, c.Name, c.OrderCount });
для этого примера. - person Mark G   schedule 11.03.2020.Concat
LINQ, который преобразуется вUNION ALL
; в первую последовательность включают поля, а во вторую последовательность не включают поля. - person Zev Spitz   schedule 11.03.2020