Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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复合DTO到ViewModel的转换_C#_Automapper - Fatal编程技术网

C# Automapper复合DTO到ViewModel的转换

C# Automapper复合DTO到ViewModel的转换,c#,automapper,C#,Automapper,在某些情况下,需要从我们的存储库返回复合DTO,其中DTO只有几个属于模型属性的属性,DTO的功能只是作为一个简单的复合对象(返回一个可查询的对象是不够的,因为信息比T多) 例如: 型号: public class Job { int Id { get; set; } //more properties } public class JobApplication { int Id { get; set; } //more properties } 存储库: I

在某些情况下,需要从我们的存储库返回复合DTO,其中DTO只有几个属于模型属性的属性,DTO的功能只是作为一个简单的复合对象(返回一个可查询的对象是不够的,因为信息比T多)

例如:

型号:

public class Job
{
    int Id { get; set; }
    //more properties
}

public class JobApplication
{
    int Id { get; set; }
    //more properties
}
存储库:
IQueryable GetJobAndMatchingUserId应用程序(int userId)

现在-我只想做(Project和to是Automapper功能):

//这允许一个有效的查询引入复合DTO的子属性
var jobVmList=jobRepository.GetAllJobsAndMatchingJobApplicationByUser(用户ID)
.Project(项目)
.至()
.ToList();
所以我需要这样一种映射:

Mapper.CreateMap<JobAndUserApplication, JobVM>()
      .ForMember(jvm => jvm, opt => opt.ResolveUsing(src => src.Job));
      //many other .ForMembers that are not relevant right now
Mapper.CreateMap()
.ForMember(jvm=>jvm,opt=>opt.resolvesusing(src=>src.Job));
//许多其他的。目前不相关的成员
我试图将DTO的Job属性直接映射到JobVM(它共享许多相同的属性)

我的映射引发以下异常:

仅对类型上的顶级单个成员支持成员的自定义配置

我做错了什么?如何在JobVM本身上完成DTO的Job属性的映射


感谢Automapper告诉您,您只能在类的成员(属性)上定义自定义操作,而不能在类本身上定义自定义操作。您需要做的是首先创建一个Job-to-JobVM映射:

Mapper.CreateMap<Job, JobVM>()
Mapper.CreateMap()

Mapper.CreateMap()
确保忽略并设置这两种类型的任何重复属性。然后运行automapper两次,首先从子对象:

var jobVM = Mapper.Map<Job, JobVM>(jobAndUserApplication.job);
var jobVM=Mapper.Map(jobAndUserApplication.job);
然后从父对象

Mapper.Map<JobAndUserApplication, JobVM>(jobAndUserApplication, jobVM );
Mapper.Map(jobAndUserApplication,jobVM);
或者反过来,这取决于你的财产是如何布置的


快速补充说明:我有一种感觉,您可能在混合担忧,我的代码气味警报正在响。我想再看一看您的viewmodel或domain模型,因为这不是我看到出现的典型问题。(只有我的$0.02:-)

谢谢杰森。我试图避免调用Map方法两次——这不是一个大问题,但我认为AutoMapper的丰富配置应该允许我配置映射,这样我只需要调用Map一次。我将在另一条评论中回应代码气味。我们的存储库只返回模型,我们的服务层在存储库和返回DTO上运行。在服务中调用多个存储库方法以将返回的结果粘合在一起是一个不必要的性能问题(多个查询和不必要的内存处理,数据库做得很好)。据我所知,除了使用复合类(将两个模型粘在一起)返回模型,以运行一个无需内存处理的select高效查询之外,没有其他方法。这是因为AFAIK Automapper无法处理匿名类型。啊,这是有道理的。您可以采取的另一种方法是在中设置自定义映射逻辑。AfterMap()使用匿名函数定义自定义映射逻辑,这可以帮助您避免第二次调用。感谢Jason-我已经尝试了所有这些方法,但它们都不起作用:-
.AfterMap((jaua,jvm)=>{Mapper.Map(jaua.Job,jvm);})
-
.ConstructUsing(jaua=>{Mapper.CreateMap();返回Mapper.Map(jaua.Job);})
-
.ConvertUsing(jaua=>{return Mapper.Map(jaua.Job,new JobVM());})
-
.ForMember(jvm=>jvm,opt=>opt.resolvesusing(src=>src.Job))我上传了几个月前创建的automapper POC。也许你可以把它岔开,把你遇到的问题的更多细节放在那里?我猜问题中缺少了一些我没有看到的东西。
Mapper.CreateMap<JobAndUserApplication, JobVM>()
var jobVM = Mapper.Map<Job, JobVM>(jobAndUserApplication.job);
Mapper.Map<JobAndUserApplication, JobVM>(jobAndUserApplication, jobVM );