почему список книг не отфильтрован и появляется элемент с именами N1 и N2 и как подготовить ObservableCollection - PullRequest
1 голос
/ 13 апреля 2020

У меня ниже класса и связанных с ним данных, здесь я пытаюсь отфильтровать книги с именем книги с именем "N1", но это не работает, и я получаю оба элемента книги в `filterList, пожалуйста, предложите, почему и что лучший способ заполнить наблюдаемую коллекцию на основе данных фильтра?

 var lstStudents = new List<Student>
        {
            new Student
            {
                Name = "studen1",
                Standards = new List<Standard> {new Standard {Name = "std1"}, new Standard {Name = "std2"}},
                Books = new List<Book> {new Book {Name = "N1", Page = "20"}, new Book {Name = "N2", Page = "30"}}
            },
            new Student
            {
                Name = "studen2",
                Standards = new List<Standard> {new Standard {Name = "std1"}},
                Books = new List<Book> {new Book {Name = "N1", Page = "20"}, new Book {Name = "N2", Page = "30"}}
            },
            new Student
            {
                Name = "studen3",
                Standards = new List<Standard> {new Standard {Name = "std1"}},
                Books = new List<Book> {new Book {Name = "N1", Page = "20"}, new Book {Name = "N2", Page = "30"}}
            }
        };

        var filterList = lstStudents.Where(c => c.Standards.Count == 1
                                          && c.Standards.Any(d => d.Name == "std1")
                                          && c.Books.Any(d => d.Name == "N1"))
            .ToList();
        //why both books with Name N1 & N2 both filtered as I am filtering with name = N1?

        var data = new ObservableCollection<Data>();

        foreach (var item in filterList)
        {
            data.Add(new Data { BookName = item.Name, BookPage = item.Books[0].Page });
        }

Поддерживающие классы:

 public class Data
{
    public string StudentName { get; set; }
    public string BookName { get; set; }
    public string BookPage { get; set; }
}

public class Student
{
    public string Name { get; set; }
    public List<Standard> Standards { get; set; }
    public List<Book> Books { get; set; }
}

public class Standard
{
    public string Name { get; set; }
}

public class Book
{
    public string Name { get; set; }
    public string Page { get; set; }
}

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Вы можете:
1 - отфильтровать все students, у которых count из Standards равно 1 и имени std1,
2 - и сгладить все books и student Name к Data объекту напрямую,
3 - использовать второй фильтр для книги BookName == "N1",
4 - напрямую поместить результат в ObservableCollection, как в следующем коде:

List<Data> filterList = lstStudents.Where(c => c.Standards.Count == 1 && c.Standards.Any(d => d.Name == "std1"))
    .SelectMany(x => x.Books.Select(y => new Data { StudentName = x.Name, BookName = y.Name, BookPage = y.Page }))
    .Where(d => d.BookName == "N1")
    .ToList();

var newData = new ObservableCollection<Data>(filterList);

Демо

foreach (Data data in filterList)
{
    Console.WriteLine($"StudentName:{data.StudentName} BookName:{data.BookName} BookPage:{data.BookPage}");
}

Результат

StudentName:studen2 BookName:N1 BookPage:20
StudentName:studen3 BookName:N1 BookPage:20

Надеюсь, это поможет вам.

1 голос
/ 13 апреля 2020

Ваш запрос возвращает учеников, у которых есть какая-либо книга "N1" в списке книг (вместе с другими фильтрами).

Таким образом, сами книги не отфильтровываются, просто ученики, у которых этого нет book.

Пример того, как вы можете вернуть список книг "N1" для студентов, которые соответствуют начальным фильтрам:

var filterList = lstStudents.Where(c => 
c.Standards.Count == 1
&& c.Standards.Any(d => d.Name == "std1"))
.SelectMany(s => s.Books.Select(b =>                                                                                     
new {
    StudentName = s.Name,
    BookName = b.Name,
    BookPage = b.Page
})
.Where(b => b.BookName == "N1"));

Затем, например:

foreach (var item in filterList)
    {
        data.Add(new Data { StudentName = item.StudentName, BookName = item.BookName, BookPage = item.Page });
    }

Это в первую очередь извлекает учащихся, соответствующих указанным критериям, затем извлекает книги этих учеников в один список книг (метод SelectMany).

Затем выполняется фильтрация этих книг, чтобы возвращались только те, у которых есть необходимые критерии в анонимный тип с именем студента также.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...