Automapper 为什么我会得到一个“a”;可为null的对象必须有一个值";当I';我的使用条件?

Automapper 为什么我会得到一个“a”;可为null的对象必须有一个值";当I';我的使用条件?,automapper,Automapper,在下面的示例代码中,我得到了一个“可为null的对象必须有一个值”。为什么我需要以下修复程序来实现此功能: .ForMember(dest => dest.ShirtColor, dest => dest.MapFrom(src => src.ShirtColor != null ? new OptionSetValue((int) src.ShirtColor)

在下面的示例代码中,我得到了一个“可为null的对象必须有一个值”。为什么我需要以下修复程序来实现此功能:

.ForMember(dest => dest.ShirtColor,
           dest => dest.MapFrom(src => src.ShirtColor != null
                                       ? new OptionSetValue((int) src.ShirtColor)
                                       : null))
AutoMapper.Mapper.CreateMap()
.FormMember(dest=>dest.FirstName,dest=>dest.MapFrom(src=>src.FirstName))
.FormMember(dest=>dest.LastName,dest=>dest.MapFrom(src=>src.LastName))
//避免覆盖现有数据的条件!!!
.ForMember(dest=>dest.ShirtColor,
dest=>dest.Condition(src=>src.ShirtColor!=null))
.ForMember(dest=>dest.ShirtColor,
dest=>dest.MapFrom(
src=>newoptionSetValue((int)src.ShirtColor)))
//由于以下情况,不需要修复:
//.ForMember(dest=>dest.ShirtColor,
//dest=>dest.MapFrom(
//src=>src.ShirtColor!=null
//?新选项设定值((int)src.ShirtColor)
//:null));
人物角色源=新人物角色();
source.FirstName=“托马斯”;
source.LastName=“杰斐逊”;
source.ShirtColor=null;//可空整数
PersonB destination=新的PersonB();
destination.FirstName=“托马斯”;
destination.LastName=“杰斐逊”;
destination.ShirtColor=新选项设置值(4);
//结果是:“可空对象必须有值”,尽管
//条件应该已经满足了!
Mapper.Map(源、目的地);
Assert(destination.ShirtColor!=null);
WriteLine(“我们现有的数据没有被覆盖!!”;
控制台写入线(“按回车键退出”);
Console.ReadLine();
以下是OptionSet的定义: 公共类选项SetValue { 公共选项SetValue(){}

public options设置值(int值)
{
数字=数值;
}
公共整数{get;set;}
}
您需要更改

.ForMember(dest=>dest.ShirtColor,
dest=>dest.Condition(src=>src.ShirtColor!=null))

.ForMember(dest=>dest.ShirtColor,
opt=>opt.Condition(src=>!src.IsSourceValueNull))
请注意,您也不需要以下内容,因为它们是按约定映射的:

.ForMember(dest=>dest.FirstName,opt=>opt.MapFrom(src=>src.FirstName))
.ForMember(dest=>dest.LastName,opt=>opt.MapFrom(src=>src.LastName))

更新-2

这个问题与条件和映射没有结合在一起这一事实有关。我创建了一个简单的扩展方法来支持它

这里有一个测试来证明这一点

课程

公共类人物
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
公共类角色:Person
{
公共int?ShirtColor{get;set;}
}
公共类人员B:人员
{
公共选项SetValue ShirtColor{get;set;}
}
公共类选项SetValue
{
公共int optionStart{get;set;}
}
映射配置

公共类MyProfile:Profile
{
受保护的覆盖无效配置()
{
Mapper.CreateMap()
.ForMember(dest=>dest.ShirtColor,
opt=>opt.ConditionallyMapFrom(
src=>newoptionsetvalue
{
OptionSet=src.ShirtColor.Value
},
src=>src.ShirtColor.HasValue);
}
}
公共静态类扩展
{
公共静态无效条件从(
此IMemberConfiguration表达式,
表达式源成员,
Func条件)
{
表达式.条件(条件);
表达式.MapFrom(sourceMember);
}
}
单元测试

[TestFixture]
公共类映射测试
{
[测试]
public void AutoMapper_配置_IsValid()
{
初始化(m=>m.AddProfile());
assertConfigurationsValid();
}
[测试]
public void AutoMapper_ClientMapping_IsValid()
{
初始化(m=>m.AddProfile());
assertConfigurationsValid();
var source=新角色
{
FirstName=“FirstA”,
LastName=“LastA”,
衬衫颜色=空
};
var destination=新员工B
{
FirstName=“FirstB”,
LastName=“LastB”
};
destination=Mapper.Map(源、目标);
Assert.That(目的地为.Not.Null);
Assert.That(destination.FirstName,Is.EqualTo(“FirstA”);
Assert.That(destination.LastName,Is.EqualTo(“LastA”);
Assert.That(destination.ShirtColor,Is.Null);
}
}
可能会帮助某人

当有代码试图解析automapper中无效值的枚举时,我遇到了这个异常

Mapper.CreateMap<Data.Employee, Domain.Entities.Employee>().
      .ForMember(dest => dest.EmployeeType, opt => opt.MapFrom(src =>(EmployeeTypeEnum)src.EmployeeTypeId))  
  // if the EmployeeTypeId has an invalid value which does not match the enum values we get exception
我也觉得其他人可能会遇到这样的情况:您正在根据automapper内部的逻辑创建一个异常

Mapper.CreateMap<Data.Employee, Domain.Entities.Employee>().
      .ForMember(dest => dest.EmployeeType, opt => opt.MapFrom(src =>(EmployeeTypeEnum)src.EmployeeTypeId))  
  // if the EmployeeTypeId has an invalid value which does not match the enum values we get exception
Mapper.CreateMap()。
.ForMember(dest=>dest.EmployeeType,opt=>opt.MapFrom(src=>(EmployeeTypeEnum)src.EmployeeTypeId))
//如果EmployeeTypeId有一个与枚举值不匹配的无效值,则会出现异常
只需将其强制转换为可为null的
int

.ForMember((destination)         => destination.ShirtColor,
           (memberConfiguration) => memberConfiguration.MapFrom((source) => (int?)source.ShirtColor))

只需使用
前提条件
而不是
条件

所以改变你的想法

//避免覆盖现有数据的条件!!!
.ForMember(dest=>dest.ShirtColor,dest=>dest.Condition(src=>src.ShirtColor!=null))
.FormMember(dest=>dest.ShirtColor,dest=>dest.MapFrom(src=>newoptionSetValue((int)src.ShirtColor)))

//避免覆盖现有数据的条件!!!
.ForMember(dest=>dest.ShirtColor,dest=>des