Как запросить у Linq Список, который содержит список списков, который содержит список списков, который содержит список объектов? - PullRequest
0 голосов
/ 04 апреля 2020

Мне нужен список, который содержит список списков, который содержит список списков, который содержит список объектов. И я считаю, что мы можем добиться этого с помощью Linq. Но я не знаю, как!

Здесь я оставил опубликованную диаграмму для лучшего понимания того, что мне нужно.

https://i.gyazo.com/fe52e851024b0b13e6d39eeb533c43f2.png

У меня есть объект:

public class Question
{
    public int ModuleID    { get; set; }
    public int GroupID     { get; set; }
    public int QuestionID     { get; set; }
}

Я возвращаю список, который может выглядеть следующим образом:

List<Question> questionList = new List<Question>();
QuestionList.Add( new Question{ ModuleID = 1, GroupID = 1, QuestionID = 1 } );
QuestionList.Add( new Question{ ModuleID = 2, GroupID = 1, QuestionID = 2 } );
QuestionList.Add( new Question{ ModuleID = 3, GroupID = 2, QuestionID = 3 } );
QuestionList.Add( new Question{ ModuleID = 4, GroupID = 4, QuestionID = 4 } );

Что я пробовал:

var groupedCustomerList = userList
    .GroupBy(u => u.GroupID)
    .Select(grp => grp.ToList())
    .ToList();

От:

Использование Linq для группировки списка объектов в новый сгруппированный список списка объектов

И я попытался:

var groupedCustomerList = CustomerList.GroupBy(u => u.GroupID)
            .Select(grp =>new { GroupID =grp.Key, CustomerList = grp.ToList()})
            .ToList();

От:

Использование LINQ для группировки списка объектов

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Получить правильные типы. В вашем списке есть целые числа, но в классе есть строки. Используйте IEquatable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Question> questionList = new List<Question>();
            questionList.Add(new Question { ModuleID = "1", GroupID = "1", QuestionID = 1 });
            questionList.Add(new Question { ModuleID = "2", GroupID = "1", QuestionID = 2 });
            questionList.Add(new Question { ModuleID = "3", GroupID = "2", QuestionID = 3 });
            questionList.Add(new Question { ModuleID = "4", GroupID = "4", QuestionID = 4 });
            questionList.Add(new Question { ModuleID = "4", GroupID = "4", QuestionID = 4 });

            List<List<Question>> results = questionList.GroupBy(x => x).Select(x => x.ToList()).ToList();
        }
    }

    public class Question : IEquatable<Question>
    {
        public string ModuleID { get; set; }
        public string GroupID { get; set; }
        public int QuestionID { get; set; }

        public Boolean Equals(Question other)
        {
            return
                (ModuleID == other.ModuleID) &&
                (GroupID == other.GroupID) &&
                (QuestionID == other.QuestionID);
        }
        public override int GetHashCode()
        {
            return (ModuleID + "^" + GroupID + "^" + QuestionID.ToString()).GetHashCode();
        }
    }
}
0 голосов
/ 04 апреля 2020

Вот небольшое консольное приложение, которое, я думаю, демонстрирует, как получить иерархическую группировку, которую вы ищете:

internal class Program
{
    public class Module
    {
        public int ModuleID { get; set; }
        public List<Group> Groups { get; set; }
    }

    public class Group
    {
        public int GroupID { get; set; }
        public int ModuleID { get; set; }
        public List<Question> Questions { get; set; }
    }

    public class Question
    {
        public int ModuleID { get; set; }
        public int GroupID { get; set; }
        public int QuestionID { get; set; }
    }

    private static void Main(string[] args)
    {
        var questions = new List<Question>();
        questions.Add(new Question {ModuleID = 1, GroupID = 1, QuestionID = 1});
        questions.Add(new Question {ModuleID = 2, GroupID = 1, QuestionID = 2});
        questions.Add(new Question {ModuleID = 3, GroupID = 2, QuestionID = 3});
        questions.Add(new Question {ModuleID = 4, GroupID = 4, QuestionID = 4});

        var groups = questions
            .GroupBy(q => new {q.GroupID, q.ModuleID})
            .Select(qg => new Group
            {
                GroupID = qg.Key.GroupID,
                ModuleID = qg.Key.ModuleID,
                Questions = qg.ToList()
            })
            .GroupBy(g => g.ModuleID)
            .Select(gg => new Module
            {
                ModuleID = gg.Key,
                Groups = gg.ToList()
            })
            .ToList();
    }
}

Самая важная строка здесь, вероятно, .GroupBy(q => new {q.GroupID, q.ModuleID}). Группирования по GroupId недостаточно, потому что мы также должны учитывать, находятся ли Вопросы в разных модулях. Например, в примере вышеупомянутых тестовых данных это всплыло бы из-за ошибочной группировки вопросов № 1 и № 2, потому что они оба имеют одинаковые значения GroupID, игнорируя тот факт, что они находятся в разных модулях. Чтобы решить эту проблему, мы создаем новый анонимный объект, связывающийся с GroupID и ModuleID вопроса (new {q.GroupID, q.ModuleID})), и вместо этого группируем этот анонимный объект.

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