gpt4 book ai didi

c# - 如何使用 AutoMapper 正确配置 `int?` 到 `int` 投影?

转载 作者:太空狗 更新时间:2023-10-29 21:48:58 25 4
gpt4 key购买 nike

我在让它正常工作时遇到了一些麻烦。我有两个类(class):

public class TestClassA
{
public int? NullableIntProperty { get; set; }
}

public class TestClassB
{
public int NotNullableIntProperty { get; set; }
}

然后我设置了以下映射:

cfg.CreateMap<TestClassA, TestClassB>()
.ForMember(dest => dest.NotNullableIntProperty,
opt => opt.MapFrom(src => src.NullableIntProperty));

cfg.CreateMap<TestClassA, TestClassA>()
.ForMember(dest => dest.NullableIntProperty,
opt => opt.MapFrom(src => src.NullableIntProperty));

cfg.CreateMap<TestClassB, TestClassA>()
.ForMember(dest => dest.NullableIntProperty,
opt => opt.MapFrom(src => src.NotNullableIntProperty));

cfg.CreateMap<TestClassB, TestClassB>()
.ForMember(dest => dest.NotNullableIntProperty,
opt => opt.MapFrom(src => src.NotNullableIntProperty));

我现在设置了四个映射,将测试以下场景:

int? => int
int => int?
int => int
int? => int?

在测试类中,我然后使用这样的映射:

var testQueryableDest = testQueryableSrc.ProjectTo<...>(_mapper.ConfigurationProvider);

我预计在这个阶段唯一不能工作的投影是 TestClassA => TestClassB,因为我可以看到 AutoMapper 可能不知道如何处理 int? 在值为 null 的情况下。果然,正是如此。所以我为 int 设置了一个映射? => int 像这样:

cfg.CreateMap<int?, int>()
.ProjectUsing(src => src ?? default(int));

这就是事情变得奇怪的地方。一旦我添加此映射,TestClassB => TestClassB 中的映射甚至无法创建。它给出了这个错误信息:

Expression of type 'System.Int32' cannot be used for assignment to type 'System.Nullable`1[System.Int32]'

我发现此消息非常奇怪,因为 TestClassB 根本没有 int?。那么这是怎么回事?我觉得我一定是误解了 AutoMapper 如何需要处理这些投影。我意识到将各种代码拼凑起来可能很棘手,所以这里是整个测试类以供引用:

[TestClass]
public class BasicTests
{
private readonly IMapper _mapper;

public BasicTests()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<int?, int>()
.ProjectUsing(src => src ?? default(int));

cfg.CreateMap<TestClassA, TestClassB>()
.ForMember(dest => dest.IntProperty, opt => opt.MapFrom(src => src.NullableIntProperty));

cfg.CreateMap<TestClassA, TestClassA>()
.ForMember(dest => dest.NullableIntProperty, opt => opt.MapFrom(src => src.NullableIntProperty));

cfg.CreateMap<TestClassB, TestClassA>()
.ForMember(dest => dest.NullableIntProperty, opt => opt.MapFrom(src => src.IntProperty));

cfg.CreateMap<TestClassB, TestClassB>()
.ForMember(dest => dest.IntProperty, opt => opt.MapFrom(src => src.IntProperty));
});

_mapper = new Mapper(config);
}

[TestMethod]
public void CanMapNullableIntToInt()
{
var testQueryableSource = new List<TestClassA>
{
new TestClassA
{
NullableIntProperty = null
}
}.AsQueryable();

var testQueryableDestination = testQueryableSource.ProjectTo<TestClassB>(_mapper.ConfigurationProvider);
}

[TestMethod]
public void CanMapNullableIntToNullableInt()
{
var testQueryableSource = new List<TestClassA>
{
new TestClassA
{
NullableIntProperty = null
}
}.AsQueryable();

var testQueryableDestination = testQueryableSource.ProjectTo<TestClassA>(_mapper.ConfigurationProvider);
}

[TestMethod]
public void CanMapIntToNullableInt()
{
var testQueryableSource = new List<TestClassB>
{
new TestClassB
{
IntProperty = 0
}
}.AsQueryable();

var testQueryableDestination = testQueryableSource.ProjectTo<TestClassA>(_mapper.ConfigurationProvider);
}

[TestMethod]
public void CanMapIntToInt()
{
var testQueryableSource = new List<TestClassB>
{
new TestClassB
{
IntProperty = 0
}
}.AsQueryable();

var testQueryableDestination = testQueryableSource.ProjectTo<TestClassB>(_mapper.ConfigurationProvider);
}
}

最佳答案

我发现重现这种情况的最短方法如下:

var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<int?, int>().ProjectUsing(x => x ?? default(int));
cfg.CreateMap<TestClassA, TestClassA>()
.ForMember(a => a.NullableIntPropety, o => o.MapFrom(a => a.NullableIntProperty));
}

在我看来,AutoMapper 正在尝试使用 int? => int 映射器在这里,虽然更明显的基于身份的映射将在这里使用。

由于每个 int 也是一个有效的 int?,AutoMapper 尝试使用 int? => int 映射器并将结果分配给 int? 成员。但似乎在解决该任务时,某些事情在幕后无法正常工作,因此出现了异常。

解决它的方法似乎是添加另一个映射,int 的恒等映射? => int?:

cfg.CreateMap<int?, int?>().ProjectUsing(x => x);

然后,将改用此映射并且不会发生异常(并且映射也可以正常工作——适用于您的所有示例)。


这个问题似乎存在于当前的 AutoMapper 5.1.x 版本(当前是 5.1.1)。好消息是,它已经被修复了。如果您尝试来自 myget feed 的当前 5.2 alpha ,那么代码可以正常工作,没有任何问题。

自 5.1.1 版本发布以来,代码库已经做出了相当多的贡献,对可空映射进行了多项修复(例如 thisthis 拉取请求)。我认为其中一项更改已经解决了这个问题。

很可能是拉取请求 #1672这只是为了删除不需要的代码,但显然也修复了 issue 1664这是关于 AutoMapper 显然优先考虑可空源映射而不是不可空源,即使正在映射不可空源也是如此。这听起来很像您遇到的这个问题。

因此,目前,您可以添加上述解决方法以将类型映射到自身或使​​用 alpha 版本,同时我们等待 5.2 发布。

关于c# - 如何使用 AutoMapper 正确配置 `int?` 到 `int` 投影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39992066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com