Linq для фильтрации вложенного списка

#c# #linq

#c# #linq

Вопрос:

Хорошо, я написал LINQ to Entities запрос ниже (достаточно близко к моему запросу c #, показанному ниже)

 var itemss = filteredstudents
.Where(x => x.SubjectTypes.Any(y => y.SubjectItem.Any(z => z.Name  == value1))).ToList();
  

все еще небольшая проблема, потому что, когда тип SubjectItem имеет два элемента, и один из них соответствует value1 . он по-прежнему возвращает оба. Он должен возвращать только соответствующую запись. Я знаю, что проблема в любом, но не уверен Any , что заменить на что?

 foreach (StudentDTO student in filteredstudents)
{
    bool valid = true;
    foreach (SubjectTypes subjectType in student.SubjectTypes)
    {
        string value1 = subjectType.SubjectItem.Select(x => x.value1).First();
        Guid StId = _context.Items.Where(x => x.Name == value1).FirstOrDefault();

        if (StId != null)
            valid = true;
        else
        {
            valid = false;
            _log("create log");
        }
    }
    if (valid)
        filteredstudentsWithUnits.Add(student);
}
  

Пример ввода

 {"Name":"ABC",
"Age":12,
,"SubjectTypes":
[
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"bbb"}]}
]
}
  

Ожидаемый результат

 {"Name":"ABC",
"Age":12,
,"SubjectTypes":
[
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},

]
}
  

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

1. пожалуйста, поделитесь отношениями между SubjectTypes и SubjectItem

2. Также будет полезно, если вы опубликуете пример данных и ожидаемый результат

3. Можете ли вы объяснить, что должно произойти в случае нескольких элементов? Должен ли он возвращаться только в том случае, если есть один элемент, и он соответствует, и если да, то в чем проблема, с которой вы сталкиваетесь при этом (кажется, не сложнее, чем другие вещи, которые вы здесь делаете)

4. Он должен просто возвращать / фильтровать только совпадающие данные.

5. @ Gilad Green, я обновил свой вопрос с помощью примера входных и ожидаемых выходных данных. Его формат json.

Ответ №1:

Вы можете сначала отфильтровать список .Where , а затем использовать .Select для проецирования в новую коллекцию, содержащую только нужные вам данные. Может работать что-то вроде следующего:

 var itemss = filteredstudents
    .Where(s => s.SubjectTypes.Any(st => st.SubjectItem.Any(si => si.Name  == value1)))
    .Select(s => new StudentDTO
    {
        Name = s.Name,
        Age = s.Age,
        SubjectTypes = s.SubjectTypes.Where(st => st.SubjectItem.Any(si => si.Name  == value1))
            .Select(st => new SubjectType
            {
                Id = st.Id,
                Description = st.Description,
                SubjectItem = st.SubjectItem.Where(si => si.Name == value1).ToList()
            }).ToList()
    })
    .ToList();
  

Ответ №2:

Это решит вашу проблему, но могут быть и лучшие способы сделать это, также я опустил некоторые свойства, такие как идентификаторы и метки, которые вам нужно будет добавить.

 var items = filteredstudents.Select(s => new StudentDTO
{
    Name = s.Name,
    SubjectTypes = s.SubjectTypes.Select(st => new SubjectType
    {
        Description = st.Description,
        SubjectItems = st.SubjectItems.Where(si => si.Name == "AAA").ToList()
    }).Where(x => x.SubjectItems.Count > 0).ToList()
});
  

Ответ №3:

Приведенная ниже логика может помочь вам фильтровать только вложенный список.

Например:

Рассмотрим приведенную ниже структуру классов:

 class EntityName { int i; string xx; List<SubEntity> subEntityName; }
  

Затем отфильтруйте только такие subEntity детали, как это.

 objEntity.SubEntityName = objEntity.SubEntityName.Where(x=>x.attrubute== "")"