如何解决使用自动映射器手动映射对象列表
我正在使用自动映射器将一个复杂的对象映射到另一个对象,在该对象中,源对象具有其属性与目标中的对象列表不匹配的对象列表。
因此,我正在使用Linq手动遍历源代码中的列表,并将其映射到目标对象。
问题是,目标对象是数据库对象:
源对象:
public class AutomationDetailsResponse
{
public Guid ServiceId { get; set; }
public int EngagementId { get; set; }
public string ServiceRequestName { get; set; }
public Guid ServiceRequestGUID { get; set; }
public string OfficeId { get; set; }
public string CountryId { get; set; }
public string EngagementCode { get; set; }
public string CanvasDocumentUri { get; set; }
public string CanvasAudienceUri { get; set; }
public List<RequestFile> InputRequestFiles { get; set; }
public List<RequestFile> OutputRequestFiles { get; set; }
public string Status { get; set; }
public string RequestInitiatedByName { get; set; }
public string RequestInitiatedBy { get; set; }
public int DataCenterId { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime LastUpdatedAt { get; set; }
public List<ActivityFeed> ActivityFeeds { get; set; }
public List<Guid> TaskIds { get; set; }
[JsonProperty("Id")]
public int CanvasRequestId { get; set; }
}
public class RequestFile
{
public Guid Id { get; set; }
public int FileSequence { get; set; }
public Guid GroupId { get; set; }
public string GroupName { get; set; }
public string FileType { get; set; }
public string FileName { get; set; }
public int FileSize { get; set; }
public Guid DocumentId { get; set; }
public DateTime CreatedAt { get; set; }
}
public class ActivityFeed
{
public int CreatedById { get; set; }
public DateTime CreatedAt { get; set; }
public string Description { get; set; }
public int ActivityType { get; set; }
public string UserName { get; set; }
public int Id { get; set; }
}
目标对象:
[Table(nameof(AutomationRequest),Schema = Schemas.SAH)]
public class AutomationRequest : EntityBase,ICreatedDate,IModifiedDate
{
[Required]
public int CanvasEnvironmentId { get; set; }
[Required]
public Guid AppInstanceId { get; set; }
public Guid CanvasRequestGUID { get; set; }
public int CanvasRequestId { get; set; }
public int DownstreamStatusId { get; set; }
[Required]
public int CanvasStatusId { get; set; }
[Required]
public Guid ServiceCatalogId { get; set; }
[Required]
public string RequestName { get; set; }
[Required]
[MaxLength(255)]
public string EngagementId { get; set; }
[Required]
public int CountryId { get; set; }
[Required]
public int DataCenterId { get; set; }
public bool IsDeletedFromSAH { get; set; }
public bool IsDeletedFromCAH { get; set; }
[MaxLength(500)]
public string CreatedByEmail { get; set; }
[MaxLength(500)]
public string CreatedByName { get; set; }
[Required]
public DateTime CreatedDate { get; set; }
[MaxLength(38)]
public string ModifiedBy { get; set; }
[MaxLength(50)]
public string OriginatedFrom { get; set; }
[Required]
public DateTime ModifiedDate { get; set; }
public string NavigationUrl { get; set; }
public int? Version { get; set; }
[ForeignKey(nameof(CanvasEnvironmentId))]
public virtual Environment CanvasEnvironment { get; set; }
[ForeignKey(nameof(CountryId))]
public virtual Country Country { get; set; }
[ForeignKey(nameof(ServiceCatalogId))]
public virtual ServiceCatalog ServiceCatalog { get; set; }
[ForeignKey(nameof(CanvasStatusId))]
public virtual AutomationRequestStatus CanvasStatus { get; set; }
public virtual ICollection<AutomationRequestInputFile> InputFiles { get; set; }
public virtual ICollection<AutomationRequestOutputFile> OutputFiles { get; set; }
public virtual ICollection<AutomationRequestTask> Tasks { get; set; }
}
[Table(nameof(AutomationRequestInputFile),Schema = Schemas.SAH)]
public class AutomationRequestInputFile : EntityBase,IModifiedDate
{
[Required]
public Guid CanvasGroupId { get; set; }
public Guid CanvasDocumentId { get; set; }
[MaxLength(255)]
public string FileName { get; set; }
[MaxLength(38)]
public string CreatedBy { get; set; }
[Required]
public DateTime CreatedDate { get; set; }
[MaxLength(38)]
public string ModifiedBy { get; set; }
[Required]
public DateTime ModifiedDate { get; set; }
[Required]
public Guid AutomationRequestId { get; set; }
public string FileType { get; set; }
[ForeignKey(nameof(AutomationRequestId))]
public virtual AutomationRequest AutomationRequest { get; set; }
}
public class EntityBase
{
public EntityBase()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
}
这是映射配置:
CreateMap<AutomationDetailsResponse,AutomationRequest>()
.ForMember(dst => dst.Id,opt => opt.Ignore())
.ForMember(
dst => dst.CanvasRequestGUID,opt => opt.MapFrom(src => src.ServiceRequestGUID))
.ForMember(
dst => dst.RequestName,opt => opt.MapFrom(src => src.ServiceRequestName))
.ForMember(
dst => dst.InputFiles,opt => opt.MapFrom(src => src.InputRequestFiles.Select(x => new AutomationRequestInputFile { CanvasGroupId = x.GroupId,CanvasDocumentId = x.DocumentId,FileName = x.FileName,FileType = x.FileType })))
.ForMember(
dst => dst.OutputFiles,opt => opt.MapFrom(src => src.OutputRequestFiles.Select(x => new AutomationRequestOutputFile { CanvasDocumentId = x.DocumentId,FileType = x.FileType,FileSize = x.FileSize,CreatedDate = x.CreatedAt })))
.ForMember(
dst => dst.CreatedByName,opt => opt.MapFrom(src => src.RequestInitiatedByName))
.ForMember(
dst => dst.CreatedDate,opt => opt.MapFrom(src => src.CreatedAt))
.ForMember(
dst => dst.ModifiedDate,opt => opt.MapFrom(src => src.LastUpdatedAt))
.ForMember(
dst => dst.Tasks,opt => opt.MapFrom(src => src.TaskIds.Select(x => new AutomationRequestTask { CanvasId = x })))
;
映射有效。问题是这样的:
var automation = await _dbContext.AutomationRequests.FirstOrDefaultAsync(x => x.CanvasRequestGUID == automationDetails.ServiceRequestGUID);
_mapper.Map(automationDetails,automation);
_dbContext.Update(automation);
await _dbContext.SaveChangesAsync();
更新失败,因为在映射配置中,我们将创建一个新实例AutomationRequestInputFile,该实例将触发EntityBase中的构造函数,并创建一个新ID。 EF Core尝试更新该行时,由于ID已更改,因此找不到该记录。
我已经尝试解决这一问题了1天,但还没有取得任何进展。
感谢您的帮助。
谢谢。
解决方法
您没有正确使用AutoMapper,因为您仍在手动构造AutomationRequestInputFile
对象(通过使用LINQ .Select())。
解决方案是为RequestFile
向AutomationRequestInputFile
添加第二个映射,并删除“ InputFiles”属性的MapFrom配置中的“选择”。
这是一个有效的.NET小提琴(省略了您的问题中未提供的属性和类型):https://dotnetfiddle.net/9qizfk
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。