Colonel_Joll
Colonel_Joll

Reputation: 15

Automapper one-to-many relationship

I have a method that creates a Course. The Course retains the Teacher and their id. But after adding the Course, TeacherID has the value but Teacher has null. I think the problem is in the mapping. CourseAddRequest only has a teacherID, how can I add a Teacher?

AddCourse:

public CourseResponse AddCourse(CourseAddRequest courseAddRequest, Guid teacherId)
        {
            var teacher = _uniDbContext.Teachers
                .Include(t => t.Courses)
                .SingleOrDefault(t => t.Id == teacherId);

            if (teacher == null)
                throw new Exception("User doesn't exist");

            var course = _mapper.Map<Course>(courseAddRequest);
            teacher.Courses.Add(course);
            _uniDbContext.Teachers.Update(teacher);
            _uniDbContext.Courses.Update(course);
            _uniDbContext.Courses.Add(course);
            _uniDbContext.SaveChanges();
            return _mapper.Map<CourseResponse>(course);
        }

Course:

public class Course : BaseEntity
    {
        public string Header { get; set; }
        public string Description { get; set; }
        public Guid TeacherId { get; set; }
        public Teacher Teacher { get; set; }

        public List<Student> StudentsOnCourse { get; set; } = new List<Student>();
    }

CourseResponse:

public class CourseResponse
    {
        public Guid Id { get; set; }
        public string Header { get; set; }
        public string Description { get; set; }

        public TeacherResponse Teacher { get; set; }
        public Guid TeacherId { get; set; }
        public IEnumerable<StudentResponse> Students { get; set; }
    }

CourseAddRequest:

public class CourseAddRequest
    {
        public string Header { get; set; }
        public string Description { get; set; }
        public Guid TeacherId { get; set; }
    }

CourseProfile:

public class CourseProfile : Profile
    {
        public CourseProfile()
        {
            CreateMap<CourseAddRequest, Course>();
            CreateMap<Course, CourseResponse>();
        }
    }

TeacherProfile:

public class TeacherProfile : Profile
    {
        public TeacherProfile()
        {
            CreateMap<TeacherAddRequest, Teacher>();
            CreateMap<Teacher, TeacherResponse>();
        }
    }

Upvotes: 1

Views: 1064

Answers (1)

Ibrahim Abdelkareem
Ibrahim Abdelkareem

Reputation: 973

You guessed right. When you execute the mapping from CourseAddRequest to Course it has no Teacher Therefore the Course teach will be null.

var course = _mapper.Map<Course>(courseAddRequest);

Assuming you're using EntityFramework or another ORM it'll be able to do the insertion correctly due to the existence of the Teacher that you've referenced in the Course via TeacherId property.

And while you add the Course to the teacher's in line 11 of your method, This still leaves the Teacher property null in course. As a result, when you map it to CourseResponse you get null.

There's two way to fix this, First, you can add the teach to your course object So the mapper finds the teacher before mapping to CourseResponse in the return statement.

course.Teacher = teacher;

Or map the teacher object directly to the response.

var courseResponse = _mapper.Map<CourseResponse>(course);
courseResponse.Teacher = _mapper.Map<TeacherResponse>(teacher);
return courseResponse;

Upvotes: 1

Related Questions