如何映射(使用 AutoMapper)在 ASP.NET CORE 3.1.1 中具有外键的实体(C#,EntityFrameworkCore)

How to Map (using AutoMapper) entities that have a ForeignKey in ASP.NET CORE 3.1.1 (C#,EntityFrameworkCore)

我的控制器中有创建实体的函数:

    [HttpPost]
    [ProducesResponseType(typeof(ConnectionDBResponse), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<ActionResult<ConnectionDBResponse>> PostConnectionDB([FromBody] CreateConnectionDBQuery query)
    {
        var connectionDBs = _mapper.Map<ConnectionDBDataModel>(query);
        _context.ConnectionDB.Add(connectionDBs);
        await _context.SaveChangesAsync();

        var connectionDBResponse = _mapper.Map<ConnectionDBResponse>(connectionDBs);
        return CreatedAtAction(nameof(GetAllConnectionDB), new { id = connectionDBs.Id }, connectionDBResponse);
    }

为此,我在这两个 类 之间映射: 响应 Class:

public class CreateConnectionDBQuery
{
    public string ServerType { get; set; }
    public string ServerName { get; set; }
    public string port { get; set; }
    public string AuthType { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string DBName { get; set; }
    public string FolderName { get; set; }
    public ScheduleConfigResponse ScheduleConfig { get; set; }
    public Boolean hasEmails { get; set; }
    public EmailConfigResponse EmailConfig { get; set; }
}

public class CreateScheduleConfigQuery
{
    public string HourOfSave { get; set; }
    public int NumDaysInDB { get; set; }
    public CreateConnectionDBQuery ConnDB { get; set; }
    public int ConnDBForeignKey { get; set; }
}

public class CreateEmailConfigQuery
{
    public string SuccesEmail { get; set; }
    public string FailureEmail { get; set; }
    public CreateConnectionDBQuery ConnDB { get; set; }
    public int ConnDBForeignKey { get; set; }
}

和数据模型Class:

[Table("ConnectionDB")]
public class ConnectionDBDataModel
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string ServerType { get; set; }
    [Required]
    public string ServerName { get; set; }
    public string port { get; set; }
    public string AuthType { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    [Required]
    public string DBName { get; set; }
    [Required]
    public string FolderName { get; set; }
    public ScheduleConfigDataModel ScheduleConfig { get; set; }
    public Boolean hasEmails { get; set; }
    public EmailConfigDataModel EmailConfig { get; set; }
}

[Table("ScheduleConfig")]
public class ScheduleConfigDataModel
{
    [Key]
    public int Id { get; set; }
    public string HourOfSave { get; set; }
    public int NumDaysInDB { get; set; }

    public int ConnDBForeignKey { get; set; }
    public ConnectionDBDataModel ConnDB { get; set; }
}

[Table("EmailConfig")]
public class EmailConfigDataModel
{
    [Key]
    public int Id { get; set; }
    public string SuccesEmail { get; set; }
    public string FailureEmail { get; set; }

    public int ConnDBForeignKey { get; set; }
    public ConnectionDBDataModel ConnDB { get; set; }
}

为此,我使用 AutoMapper 如下:

        #region ConnectionDB

        CreateMap<ConnectionDBDataModel, ConnectionDBResponse>();

        CreateMap<CreateConnectionDBQuery, ConnectionDBDataModel>()
            .ForMember(dest => dest.Id, opt => opt.Ignore());

        CreateMap<UpdateConnectionDBQuery, ConnectionDBDataModel>()
            .ForMember(dest => dest.Id, opt => opt.Ignore());

        #endregion

        #region ScheduleConfig

        CreateMap<ScheduleConfigDataModel, ScheduleConfigResponse>()
            .ForMember(dest => dest.ConnDBForeignKey, opt => opt.Ignore());

        CreateMap<CreateScheduleConfigQuery, ScheduleConfigDataModel>()
            .ForMember(dest => dest.Id, opt => opt.Ignore())
            .ForMember(dest => dest.ConnDBForeignKey, opt => opt.Ignore());

        CreateMap<UpdateScheduleConfigQuery, ScheduleConfigDataModel>()
            .ForMember(dest => dest.Id, opt => opt.Ignore());

        #endregion ScheduleConfig

        #region EmailConfig

        CreateMap<EmailConfigDataModel, EmailConfigResponse>()
            .ForMember(dest => dest.ConnDBForeignKey, opt => opt.Ignore());

        CreateMap<CreateEmailConfigQuery, EmailConfigDataModel>()
            .ForMember(dest => dest.Id, opt => opt.Ignore())
            .ForMember(dest => dest.ConnDBForeignKey, opt => opt.Ignore());

        CreateMap<UpdateEmailConfigQuery, EmailConfigDataModel>()
            .ForMember(dest => dest.Id, opt => opt.Ignore());

        #endregion

但是当我尝试创建这个元素时,它给我一个错误,说它来自一个无效的映射,如下面的屏幕所示:

我曾尝试使用以下代码行忽略外键(因为我猜这个问题是由外键引起的):.ForMember(dest => dest.ConnDBForeignKey, opt => opt.Ignore());,但我想这不是解决该问题的方法。 如有任何帮助,我们将不胜感激!

发生错误是因为将 CreateConnectionDBQuery 映射到 ConnectionDBDataModel 时,没有为 ScheduleConfig 属性的类型定义映射。

我猜在你的 CreateConnectionDBQuery 中,你的 ScheduleConfig 属性 应该是 CreateScheduleConfigQuery 类型而不是 ScheduleConfigResponse.

或者,如果您不想更改模型,可以添加从 ScheduleConfigResponseScheduleConfigDataModel 的映射配置。但这似乎不是很直观。