Выполните цикл через IEnumerable и передайте их в модель с несколькими условиями if/else

#c# #linq #conditional-statements

Вопрос:

У меня есть IEnumerable список таких объектов, как этот

 return entities.Select(g => new Model(
                g.Field1,
                g.Field2,
                g.Field3
));
 

Однако требования меняются, и мне нужно просмотреть список и проверить наличие определенного строкового поля внутри каждой сущности, а затем передать его в модель.
Если строковое поле равно определенной строке, скажем «a», то оно будет передано в модель одним способом, но когда строковое поле равно «b» или «c» или даже «d», то оно будет передано в модель другим способом, соответственно, в зависимости от типа строки, которой является поле.

 return entities.
.GroupBy(x=> x.field =="a")
.Select(g => new Model(
                g.Field1,
                g.Field2,
                g.Field3,

else
.GroupBy(x=> x.field =="b")
.Select(g => new Model(
                g.Field4,
                g.Field5,
                g.Field6,

else
.GroupBy(x=> x.field =="c")
.Select(g => new Model(
                g.Field7,
                g.Field8,
                g.Field9,
);
 

Я подумывал о том, чтобы сделать предварительный, а затем групповой, а затем оператор if. Но не уверен, как построить соответствующий синтаксис для этого оператора linq.
Также рекомендуется ли цикл foreach в этом сценарии, если каким-то образом число сущностей может достигать нескольких сотен?

Ответ №1:

Вы можете использовать выражение переключения (новое с C# 8). Чтобы использовать его с EF, вам сначала нужно выбрать анонимный тип, содержащий все необходимые свойства, и загрузить его в память (например ToList() , с помощью ):

 return entities.Select(g => new
{
    g.field, g.Field1, g.Field2, g.Field3,
    g.Field4, g.Field5, g.Field6, G.Field7,
    g.Field8, g.Field9
}).ToList().Select(g => g.field switch
{
   "a" => new Model(g.Field1, g.Field2, g.Field3),
   "b" => new Model(g.Field4, g.Field5, g.Field6),
   "c" => new Model(g.Field7, g.Field8, g.Field9)
});
 

Комментарии:

1. Есть несколько проблем, которые здесь x.field не существуют в этой области, и маловероятно, что EF сможет перевести это на SQL.

2. Если EF не может перевести это, можно загрузить все необходимые свойства в память, а затем использовать Linq2Objects. Смотрите мой обновленный ответ.

3. @JohnathanBarclay Я только что проверил это. На самом деле, можно было бы получить ошибку компилятора «Дерево выражений может не содержать выражения переключения». Большое спасибо за подсказку.