1
\$\begingroup\$

I am return an student object from my database and I want to convert it into a StudentRecoredRequest model. The way i have implement is shown below. I was wondering if there was a nicer way to convert from the student object to studentsystemrecordrequest. Thanks

        var result = await _context.Student.ToListAsync();
        var studentInfo = new List<StudentSystemRecordRequest>();
        foreach(var student in result)
        {
            var stud = new StudentSystemRecordRequest
            {
                FirstName = student.FirstName,
                LastName = student.SurName,
                DateOfBirth = student.DateOfBirth,
                Address = student.Address1
            };
            studentInfo.Add(stud);
        }
\$\endgroup\$
  • 3
    \$\begingroup\$ This question is off-topic because it provides no context. It already has 4 votes to close out of the necessary 5. \$\endgroup\$ – pacmaninbw Jul 14 at 15:54
  • \$\begingroup\$ Apologies I didn't realize it provides no context. \$\endgroup\$ – Great Khan 2016 Jul 14 at 16:39
  • 1
    \$\begingroup\$ Please heed How do I ask a Good Question? (Have the spelling checked, too.) \$\endgroup\$ – greybeard Jul 14 at 17:37
  • 1
    \$\begingroup\$ If you could provide the rest of the function, or better, the entire class that would make the question on-topic. \$\endgroup\$ – pacmaninbw Jul 14 at 17:41
  • 1
    \$\begingroup\$ What exactly is off-topic about it? The linked guidelines don't say anything about requiring context, only that providing more context will lead to a better review. OP asked for a review of a simple self-contained mechanism that converts one thing to another, and apparently at least three people felt there was enough content for a quality review. And you seem to agree as well given your comments and up-votes! So why vote to close? \$\endgroup\$ – Jeff E Jul 14 at 17:44
2
\$\begingroup\$

When dealing with collections, it would be difficult to avoid loops. However, I can think of 3 possible ways that would help you convert objects back and forth without repeating the code.

The first one is to add a constructor to StudentRecoredRequest that accepts Student object.

Example :

public class StudentRecoredRequest
{
    public string FirstName { get; set; }
    
    public string LastName  { get; set; }
    
    public DateTime DateOfBirth   { get; set; }
    
    public string Address    { get; set; }
    
    public StudentRecoredRequest() { }
    
    public StudentRecoredRequest(Student student)
    {
        FirstName = student.FirstName;
        LastName = student.SurName;
        DateOfBirth = student.DateOfBirth;
        Address = student.Address1;     
    }               
}

with this, you would be able to pass Student object directly :

var studentInfo = new StudentRecoredRequest(stud);

And you can add more methods to handle the conversion or add more options. Another advantage is that you can define an implicit operator on the class to cast Student into StudentRecoredRequest something like :

public class StudentRecoredRequest
{
    public string FirstName { get; set; }
    
    public string LastName  { get; set; }
    
    public DateTime DateOfBirth   { get; set; }
    
    public string Address    { get; set; }
    
    public StudentRecoredRequest() { }
    
    public StudentRecoredRequest(Student student)
    {
        FirstName = student.FirstName;
        LastName = student.SurName;
        DateOfBirth = student.DateOfBirth;
        Address = student.Address1;     
    }
    
    public static implicit operator StudentRecoredRequest(Student student) => new StudentRecoredRequest(student);   
}

which would give you this :

var studentInfo = (StudentRecoredRequest) stud;

the second way is to use extensions, something like this :

public static IEnumerable<StudentRecoredRequest> ToStudentRecoredRequest(this IEnumerable<Student> students)
{
    foreach(var stud in students)
    {
        yield return new StudentSystemRecordRequest
        {
            FirstName = student.FirstName,
            LastName = student.SurName,
            DateOfBirth = student.DateOfBirth,
            Address = student.Address1
        };
    }
}

usage :

var studentInfo = result.ToStudentRecoredRequest();

The third way is to use Data Transfer Object (DTO) This DTO would make things easier for transfer data between objects, you could use this pattern to link two objects for easier maintainability and extensibility.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

You can use the LINQ syntax:

var studentInfo = 
    (from student in result
     select new StudentSystemRecordRequest
        {
            FirstName = student.FirstName,
            LastName = student.SurName,
            DateOfBirth = student.DateOfBirth,
            Address = student.Address1
        }
    ).ToList();

If you are happy with IEnumerable instead of List, you can omit ToList(), but keep in mind that in that case the resulting enumerable will be lazy, which means that the elements will be created only when the result is enumerated. But since result is probably a list, which is strict, it should not be a problem.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I did up vote your answer because it is a good one, however, this question is off-topic because it does not have context. Off-topic questions should not be answered. Please consider your actions in the future. \$\endgroup\$ – pacmaninbw Jul 14 at 15:59
1
\$\begingroup\$

The loop is a red herring; the important bit is how you're doing the conversion from one student-ish type to another. I'd start there by writing a converter method:

private static StudentSystemRecordRequest ToRecordRequest(Student student)
{
    return new StudentSystemRecordRequest
    {
        FirstName = student.FirstName,
        LastName = student.SurName,
        DateOfBirth = student.DateOfBirth,
        Address = student.Address1
    };
}

I've chosen not to make this a member method of either of the Student types because I don't want to introduce any unnecessary coupling.

Such a method will compose well with LINQ, if you really want to get rid of the foreach:

var studentInfo = result.Select(ToRecordRequest).ToList();
| improve this answer | |
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.