英文:
How do I map one object from two other objects when collections are involved?
问题
I can provide a translation of the code portion for you:
我有一个`list<x>`,其中x包含另一个对象y以及属性p。我想将我的`list<x>`映射到一个`list<z>`,其中z是一个包含y的所有属性以及属性p的对象。在下面的代码中,它成功地处理了属性p,但未能映射对象y的属性。
基本上,我希望通过更智能的Profile而不是需要foreach循环来使下面的单元测试通过。
```csharp
使用AutoMapper;
使用System.Collections.Generic;
使用System.Linq;
使用FluentAssertions;
使用Xunit;
命名空间测试;
public class问题
{
[事实]
public void应该映射()
{
// 安排
var mapper = new MapperConfiguration(cfg => { cfg.AddProfile<MyMappingProfile>(); }).CreateMapper();
var inner = new InnerSource() { MyProperty1 = 1, MyProperty2 = 2 };
var outer = new OuterSource() { Inner = inner, MyCount = 7 };
var list = new List<OuterSource>() { outer };
// 行动
var result = mapper.Map<IEnumerable<Destination>>(list);
// 断言
var dest = result.First();
dest.MyBool.Should().BeTrue(); //成功!
dest.MyProperty1.Should().Be(1); //失败
//失败消息:预期dest.MyProperty1为1,但发现0(差异为-1)。
dest.MyProperty2.Should().Be(2); //也失败
}
}
public类目的
{
公共int MyProperty1 { 获取; 设置; }
公共int MyProperty2 { 获取; 设置; }
公共bool MyBool { 获取; 设置; }
}
public类InnerSource
{
公共int MyProperty1 { 获取; 设置; }
公共int MyProperty2 { 获取; 设置; }
}
public类OuterSource
{
公共InnerSource Inner { 获取; 设置; } = null!;
公共int MyCount { 获取; 设置; }
}
public类MyMappingProfile:Profile
{
public MyMappingProfile()
{
CreateMap<InnerSource, Destination>();
CreateMap<OuterSource, Destination>()
.ForMember(dest => dest.MyBool, opt => opt.MapFrom(src => src.MyCount > 0));
}
}
请注意,我只提供了代码的翻译部分,没有包括注释或其他文本。如果您需要更多信息,请告诉我。
英文:
I have a list<x>
where x contains another object y as well as a property p. I want to map my list<x>
into a list<z>
where z is an object that contains all of the properties of y plus property p. In the code below, it succeeds with property p but fails to map the properties of object y.
Basically, I want to get the unit test below to pass. I'm hoping this can be done with a smarter Profile instead of requiring a foreach loop.
using AutoMapper;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using Xunit;
namespace Test;
public class TheProblem
{
[Fact]
public void ShouldMap()
{
// Arrange
var mapper = new MapperConfiguration(cfg => { cfg.AddProfile<MyMappingProfile>(); }).CreateMapper();
var inner = new InnerSource() { MyProperty1 = 1, MyProperty2 = 2 };
var outer = new OuterSource() { Inner = inner, MyCount = 7 };
var list = new List<OuterSource>() { outer };
// Act
var result = mapper.Map<IEnumerable<Destination>>(list);
// Assert
var dest = result.First();
dest.MyBool.Should().BeTrue(); //passes!
dest.MyProperty1.Should().Be(1); //fails
//Failure Message: Expected dest.MyProperty1 to be 1, but found 0 (difference of - 1).
dest.MyProperty2.Should().Be(2); //also fails
}
}
public class Destination
{
public int MyProperty1 { get; set; }
public int MyProperty2 { get; set; }
public bool MyBool { get; set; }
}
public class InnerSource
{
public int MyProperty1 { get; set; }
public int MyProperty2 { get; set; }
}
public class OuterSource
{
public InnerSource Inner { get; set; } = null!;
public int MyCount { get; set; }
}
public class MyMappingProfile : Profile
{
public MyMappingProfile()
{
CreateMap<InnerSource, Destination>();
CreateMap<OuterSource, Destination>()
.ForMember(dest => dest.MyBool, opt => opt.MapFrom(src => src.MyCount > 0));
}
}
答案1
得分: 0
答案似乎在ConstructUsing()
方法中。我在其中一个相关问题的底部偶然找到了答案。奇怪的是,这个线程在我最初搜索答案时没有出现(在发布之前我阅读了大约10个问题,所以我认为我很仔细)。不管怎样,将这个添加到CreateMap
中解决了它:
.ConstructUsing((src, ctx) => ctx.Mapper.Map<Destination>(src.Inner))
英文:
The answer appears to lie in the ConstructUsing() method.
I stumbled across the answer in one of the related questions it put at the bottom. Strangely, that thread didn't turn up in my original search for answers (I read about 10 before posting, so I thought I was thorough).
Anyway adding this to the CreateMap solved it:
.ConstructUsing((src, ctx) => ctx.Mapper.Map<Destination>(src.Inner))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论