首页 > 解决方案 > 如何在 ASP.NET CORE 3.1.1 (C#,EntityFrameworkCore) 中映射(使用 AutoMapper)具有 ForeignKey 的实体

问题描述

我的控制器中有这个函数可以创建一个实体:

    [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);
    }

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

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; }
}

和 dataModel 类:

[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

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

enter image description here

我试图使用这行代码忽略外键(因为我猜这个问题来自外键):.ForMember(dest => dest.ConnDBForeignKey, opt => opt.Ignore());但我想这不是解决这个问题的方法。任何帮助将不胜感激,谢谢!

标签: c#asp.net-coreentity-framework-coreautomapper

解决方案


The error is happening because when mapping CreateConnectionDBQuery to ConnectionDBDataModel, there is no mapping defined for the types of the ScheduleConfig properties.

I'm guessing that in your CreateConnectionDBQuery, your ScheduleConfig property should be of type CreateScheduleConfigQuery instead of ScheduleConfigResponse.

Alternatively, if you don't want to change the models, you could add a mapping configuration from ScheduleConfigResponse to ScheduleConfigDataModel. But that doesn't seem very intuitive.


推荐阅读