Search code examples
c#.netlinqdto

How can I populate a collection inside a DTO with LINQ?


I created the following DTO:

    public class TestAndQuestionDTO
    {
        public string Name { get; set; }
        public int QuestionsCount { get; set; }
        public ICollection<TestAndQuestionDTO.Questions> TestQuestions { get; set; }

        public class Questions
        {
            public Guid QuestionUId { get; set; }
        }
    }

I am trying to populate this with LINQ but I am stuck on how to populate the inner Questions class.

Here is what I have so far:

    var result = await db.Tests
            .Include(t => t.TestQuestions)
            .Where(t => t.TestId == id)
            .Select(t => new TestAndQuestionDTO
            {
                Name = t.Title,
                TestQuestions = new TestAndQuestionDTO.Questions
                {
                    QuestionUId = t.TestQuestions. ????
                }

            })
            .ToListAsync();

Can someone tell me how I can populate the TestQuestions collection field with the data that is brought back from my collection: .Include(t => t.TestQuestions) Do I have to for example have a constructor in the TestAndQuestionDTO to create a collection of TestQuestions?

Here's my Test class for reference:

public partial class Test
{
    public Test()
    {
        this.TestQuestions = new HashSet<TestQuestion>();
    }

    public int TestId { get; set; }
    public string Title { get; set; }
    public virtual ICollection<TestQuestion> TestQuestions { get; set; }

}

Solution

  • You can use another Select to convert into your Questions DTO like this:

    var result = await db.Tests
            .Include(t => t.TestQuestions)
            .Where(t => t.TestId == id)
            .Select(t => new TestAndQuestionDTO
            {
                Name = t.Title,
                TestQuestions = t.TestQuestions.Select(tq => new TestAndQuestionDTO.Questions
                {
                    QuestionUId = tq.QuestionUId,
                    //fill in your Questions DTO here
                })
    
            })
            .ToListAsync();
    

    If you need TestAndQuestionDTO.Questions to be an ICollection<> type, change it to this:

    var result = await db.Tests
            .Include(t => t.TestQuestions)
            .Where(t => t.TestId == id)
            .Select(t => new TestAndQuestionDTO
            {
                Name = t.Title,
                TestQuestions = new Collection<TestAndQuestionDTO.Questions>(
                    t.TestQuestions.Select(tq => new TestAndQuestionDTO.Questions
                    {
                        QuestionUId = tq.QuestionUId,
                        //fill in your Questions DTO here
                    }).ToList())
            })
            .ToListAsync();