Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用automapper手动映射对象列表_C#_Asp.net Core_.net Core_Entity Framework Core_Automapper - Fatal编程技术网

C# 使用automapper手动映射对象列表

C# 使用automapper手动映射对象列表,c#,asp.net-core,.net-core,entity-framework-core,automapper,C#,Asp.net Core,.net Core,Entity Framework Core,Automapper,我使用automapper将一个复杂对象映射到另一个复杂对象,其中源对象有一个属性与目标中的对象列表不匹配的对象列表 因此,我使用Linq手动遍历源中的列表,并将其映射到目标对象 问题是,目标对象是数据库对象: 源对象: public class AutomationDetailsResponse { public Guid ServiceId { get; set; } public int Engagement

我使用automapper将一个复杂对象映射到另一个复杂对象,其中源对象有一个属性与目标中的对象列表不匹配的对象列表

因此,我使用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; }
    }
这是映射配置:

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,FileName = x.FileName, 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 })))
                ;
更新失败,因为在映射配置中,我们正在创建一个新实例AutomationRequestInputFile,该实例将触发EntityBase中的构造函数,并创建一个新Id。当EF Core尝试更新行时,它找不到记录,因为Id已更改

我已经尝试解决这个问题一天了,但没有任何进展

感谢您的帮助


谢谢。

您没有正确使用AutoMapper,因为您仍然在手动构造
AutomationRequestInputFile
对象(通过使用LINQ.Select())

解决方案是为
RequestFile
添加第二个映射到
AutomationRequestInputFile
,并删除“InputFiles”属性的MapFrom配置中的Select


这里有一个正在运行的.NET文件(您的问题中未提供的属性和类型已被省略):

您没有正确使用AutoMapper,因为您仍然在手动构造
AutomationRequestInputFile
对象(通过使用LINQ.Select())

解决方案是为
RequestFile
添加第二个映射到
AutomationRequestInputFile
,并删除“InputFiles”属性的MapFrom配置中的Select


这里有一个正在运行的.NET提琴(您的问题中未提供的属性和类型已被省略):

我认为这可以解决它。我完全按照您的建议做了,但是在映射之后仍然为每个inputrequestfile创建了一个新id,db更新仍然失败。我甚至为这个映射添加了:
.ForMember(dst=>dst.Id,opt=>opt.Ignore())
:CreateMap(),我认为这可以解决这个问题。我完全按照您的建议做了,但是在映射之后仍然为每个inputrequestfile创建了一个新id,db更新仍然失败。我甚至为此映射添加了:
.ForMember(dst=>dst.Id,opt=>opt.Ignore())
请您共享错误消息好吗?数据库操作预期会影响1行,但实际影响0行。这是一个错误,因为automapper更改了AutomationRequestInputFile的Id,当我尝试更新时,更新失败,因为EF Core无法在db中找到记录,因为Id是错误的。您需要用这段代码解决什么业务需求?从数据库中提取一条记录,然后将其映射到另一个对象并更新该记录,这听起来有点违反直觉。90%的情况下,您会从数据库中取出记录,对其进行一些更改,然后将其直接发送回数据库。为什么要将它映射到另一个对象。这是一个业务需求。您是否尝试了
\u dbContext.AutomationRequests.Update(automation)
而不是
\u dbContext.Update(automation)请共享错误消息好吗?数据库操作预期影响1行,但实际影响0行。这是一个错误,因为automapper更改了AutomationRequestInputFile的Id,当我尝试更新时,更新失败,因为EF Core无法在db中找到记录,因为Id是错误的。您需要用这段代码解决什么业务需求?从数据库中提取一条记录,然后将其映射到另一个对象并更新该记录,这听起来有点违反直觉。90%的情况下,您会从数据库中取出记录,对其进行一些更改,然后将其直接发送回数据库。为什么要将它映射到另一个对象。这是一个业务需求。您是否尝试了
\u dbContext.AutomationRequests.Update(automation)
而不是
\u dbContext.Update(automation)
[Table(nameof(AutomationRequestInputFile), Schema = Schemas.SAH)]
    public class AutomationRequestInputFile : EntityBase, ICreatedDate, 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,FileName = x.FileName, 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();