简体   繁体   中英

Automapper doesn't work for model with foreign keys

here's my Company and Employee model

public class Company
  {
    [Column( "CompanyId" )]
    public Guid Id { get; set; }

    [Required( ErrorMessage = "Company name is a required field." )]
    [MaxLength( 60, ErrorMessage = "Maximum length for the Name is 60 characters." )]
    public string Name { get; set; }

    [Required( ErrorMessage = "Company address is a required field." )]
    [MaxLength( 60, ErrorMessage = "Maximum length for the Address is 60 characters" )]
    public string Address { get; set; }

    public string Country { get; set; }
    public ICollection<Employee> Employees { get; set; }
  }

public class Employee
  {
    [Column( "EmployeeId" )]
    public Guid Id { get; set; }

    [Required( ErrorMessage = "Employee name is a required field." )]
    [MaxLength( 30, ErrorMessage = "Maximum length for the Name is 30 characters." )]
    public string Name { get; set; }

    [Required( ErrorMessage = "Age is a required field." )]
    public int Age { get; set; }

    [Required( ErrorMessage = "Position is a required field." )]
    [MaxLength( 20, ErrorMessage = "Maximum length for the Position is 20 characters." )]
    public string Position { get; set; }

    [ForeignKey( nameof( Company ) )]
    public Guid CompanyId { get; set; }

    public Company Company { get; set; }
  }

and here's my DTO

  public class EmployeeForUpdateDto
  {
    public string Name { get; set; }
    public int Age { get; set; }
    public string Position { get; set; }
  }
  public class CompanyForUpdateDto
  {
    public string Name { get; set; }
    public string Address { get; set; }
    public string Country { get; set; }
    public IEnumerable<EmployeeForCreationDto> Employees { get; set; }
  }

Here's my controller where it didnt work.

    [HttpPut( "{id}" )]
    public IActionResult UpdateEmployee( Guid companyId, Guid id, [FromBody] EmployeeForUpdateDto employee )
    {
      if( employee == null )
      {
        _logger.LogInfo( "EmployeeForUpdateDto object sent from client is null" );
        return BadRequest( "EmployeeForUpdateDto object is null" );
      }

      var company = _repository.Company.GetCompany( companyId, false );
      if( company == null )
      {
        _logger.LogInfo( $"Company with id {companyId} doesn't exist in the database" );
        return NotFound();
      }

      var employeeEntity = _repository.Employee.GetEmployee( companyId, id, true );
      if( employeeEntity == null )
      {
        _logger.LogInfo( $"Employee with id {id} doesn't exist in the database" );
        return NotFound();
      }
      _mapper.Map( employee, employeeEntity );
      _repository.Save();

      return NoContent();
    }

Basically what happens is that, the Employee doesn't get updated. I did the same route for Companies(where foreign keys didnt exist) and it got updated. Here's the controller.

    [HttpPut( "{id}" )]
    public IActionResult UpdateCompany( Guid id, [FromBody] CompanyForUpdateDto company )
    {
      if( company == null )
      {
        _logger.LogError( "CompanyForUpdateDto object sent from client is null." );
        return BadRequest( "CompanyForUpdateDto object is null" );
      }
      var companyEntity = _repository.Company.GetCompany( id, trackChanges: true );
      if( companyEntity == null )
      {
        _logger.LogInfo( $"Company with id: {id} doesn't exist in the database." );
        return NotFound();
      }
      _mapper.Map( company, companyEntity );
      _repository.Save();
      return NoContent();
    }

and in case it helps, here's my mapping profile

public class MappingProfile : Profile
  {
    public MappingProfile()
    {
      CreateMap<Company, CompanyDto>().ForMember( c => c.FullAddress, opt => opt.MapFrom( x => string.Join( ' ', x.Address, x.Country ) ) );
      CreateMap<Employee, EmployeeDto>();
      CreateMap<CompanyForCreationDto, Company>();
      CreateMap<EmployeeForCreationDto, Employee>();
      CreateMap<EmployeeForUpdateDto, Employee>();
      CreateMap<CompanyForUpdateDto, Company>();
    }
  }

Since it work in the Company but not for Employee, I figured it is because I have foreign keys in my Employee, and my mapping profile is not correct maybe?

Any help appreciated.

Couple of things that I noticed in your code -

  • Your method signature is
public IActionResult UpdateEmployee( Guid companyId, Guid id, [FromBody] EmployeeForUpdateDto employee )

DTO object shouldn't be passed to the controller as such. You could've used Employee instead

public IActionResult UpdateEmployee( Guid companyId, Guid id, [FromBody] Employee employee )
  • The Employee and EmployeeForUpdateDto are not in sync. The properties Id, CompanyId and Company are not present in EmployeeForUpdateDto.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM