C# Automapper未传输我的收藏项目
我正在使用AutoMapper 4.x 我有以下几节课:C# Automapper未传输我的收藏项目,c#,automapper,C#,Automapper,我正在使用AutoMapper 4.x 我有以下几节课: /// <summary> /// All service outputs need to descend from this class. /// </summary> public class OzCpAppServiceOutputBase : IOzCpAppServiceOutputBase { private readonly OzCpResultErrors _OzCpResultEr
/// <summary>
/// All service outputs need to descend from this class.
/// </summary>
public class OzCpAppServiceOutputBase : IOzCpAppServiceOutputBase
{
private readonly OzCpResultErrors _OzCpResultErrors;
public OzCpAppServiceOutputBase()
{
_OzCpResultErrors = new OzCpResultErrors();
}
public OzCpResultErrors ResultErrors
{
get { return _OzCpResultErrors; }
}
public bool ResultSuccess
{
get { return _OzCpResultErrors.Messages.Count == 0; }
}
}
/// <summary>
/// Return from the booking service when a simple booking is made.
/// </summary>
public class OzCpSimpleManualCruiseBookingOutput : OzCpAppServiceOutputBase
{
public int OzBookingId { get; set; }
}
}
public class SimpleManualCruiseBookingOutput : OzCpSimpleManualCruiseBookingOutput
{
}
Mapper.CreateMap<OzCpSimpleManualCruiseBookingOutput, SimpleManualCruiseBookingOutput>()
.AfterMap((src, dst) => dst.ResultErrors.Messages.AddRange(src.ResultErrors.Messages));
//
///所有服务输出都需要从该类派生。
///
公开类OzCpAppServiceOutputBase:IOzCpAppServiceOutputBase
{
私有只读OzCpResultErrors\u OzCpResultErrors;
公共OzCpAppServiceOutputBase()
{
_OzCpResultErrors=新的OzCpResultErrors();
}
公共OzCpResultErrors结果
{
获取{return\u OzCpResultErrors;}
}
公共bool ResultSuccess
{
获取{return}OzCpResultErrors.Messages.Count==0;}
}
}
///
///完成简单预订后,从预订服务返回。
///
公共类OzCPImpleManualCruiseBookingOutput:OzCPAppsServiceOutputBase
{
public int OzBookingId{get;set;}
}
}
公共类SimpleManualCruiseBookingOutput:OzCpSimpleManualCruiseBookingOutput
{
}
当我调用AutoMapper在OzCpSimpleManualCruiseBookingOutput和SimpleManualCruiseBookingOutput之间进行转换时,我的问题是结果被清除
public SimpleManualCruiseBookingOutput SimpleManualCruiseBooking(SimpleManualCruiseBookingInput aParams)
{
OzCpSimpleManualCruiseBookingOutput result = _PlatformBookingService.SimpleManualBooking(Mapper.Map<OzCpSimpleManualCruiseBookingInput>(aParams));
//**TESTING
result.ResultErrors.AddFatalError(1, "Oh Dear!!!!");
//**As soon as I perform the mapping the ResultErrros collection loses the item I have added above
return Mapper.Map<SimpleManualCruiseBookingOutput>(result);
}
public SimpleManualCruiseBooking输出SimpleManualCruiseBooking(SimpleManualCruiseBooking输入aParams)
{
ozcpsimplemanualcruisebooking输出结果=_PlatformBookingService.SimpleManualBooking(Mapper.Map(aParams));
//**测试
result.ResultErrors.AddFatalError(1,“哦,天哪!!”);
//**一旦我执行映射,ResultErrors集合就会丢失我在上面添加的项
返回Mapper.Map(结果);
}
我猜这是因为它是只读属性,但我不知道如何使它传输集合
非常感谢您的帮助
编辑
我还尝试自己在集合中添加项目,以便从以下位置更改映射:
Mapper.CreateMap<OzCpSimpleManualCruiseBookingOutput, SimpleManualCruiseBookingOutput>();
Mapper.CreateMap();
要使用后映射功能,请执行以下操作:
/// <summary>
/// All service outputs need to descend from this class.
/// </summary>
public class OzCpAppServiceOutputBase : IOzCpAppServiceOutputBase
{
private readonly OzCpResultErrors _OzCpResultErrors;
public OzCpAppServiceOutputBase()
{
_OzCpResultErrors = new OzCpResultErrors();
}
public OzCpResultErrors ResultErrors
{
get { return _OzCpResultErrors; }
}
public bool ResultSuccess
{
get { return _OzCpResultErrors.Messages.Count == 0; }
}
}
/// <summary>
/// Return from the booking service when a simple booking is made.
/// </summary>
public class OzCpSimpleManualCruiseBookingOutput : OzCpAppServiceOutputBase
{
public int OzBookingId { get; set; }
}
}
public class SimpleManualCruiseBookingOutput : OzCpSimpleManualCruiseBookingOutput
{
}
Mapper.CreateMap<OzCpSimpleManualCruiseBookingOutput, SimpleManualCruiseBookingOutput>()
.AfterMap((src, dst) => dst.ResultErrors.Messages.AddRange(src.ResultErrors.Messages));
Mapper.CreateMap()
.AfterMap((src,dst)=>dst.resultrrors.Messages.AddRange(src.resultrrors.Messages));
但这会导致目标在列表中有两个而不是一个项目,即:
这两个词都是“哦,亲爱的!!!!”
解决方案
使用DavidL建议的私有setter方法(以及对Automapper 4.x的升级)意味着我获得了所需的行为。这就是我的结局:
/// <summary>
/// Defines the contract for all output DTO's to platform
/// application services.
/// </summary>
/// <seealso cref="OzCpAppServiceOutputBase" />
public interface IOzCpAppServiceOutputBase : IOutputDto
{
/// <summary>
/// Contains a list of errors should a call to an application service fail.
/// </summary>
OzCpResultErrors ResultErrors{ get; }
/// <summary>
/// When TRUE the underlying call to the application service was successful, FALSE
/// otherwise. When FALSE see ResultErrors for more information on the error condition.
/// </summary>
bool ResultSuccess { get; }
}
public class OzCpAppServiceOutputBase : IOzCpAppServiceOutputBase
{
public OzCpAppServiceOutputBase()
{
ResultErrors = new OzCpResultErrors();
}
/// <remarks>The private setter is here so that AutoMapper works.</remarks>
public OzCpResultErrors ResultErrors { get; private set; }
public bool ResultSuccess
{
get { return ResultErrors.Messages.Count == 0; }
}
}
//
///定义平台所有输出DTO的合同
///应用程序服务。
///
///
公共接口IOzCpAppServiceOutputBase:IOutputDto
{
///
///包含应用程序服务调用失败时的错误列表。
///
OzCpResultErrors结果{get;}
///
///如果为TRUE,则对应用程序服务的基础调用成功,则为FALSE
///否则。如果为FALSE,请参阅ResultErrors以了解有关错误条件的更多信息。
///
bool ResultSuccess{get;}
}
公开类OzCpAppServiceOutputBase:IOzCpAppServiceOutputBase
{
公共OzCpAppServiceOutputBase()
{
ResultErrors=新的OzCpResultErrors();
}
///私人setter在这里,以便AutoMapper工作。
公用OzCpResultErrors结果器{get;private set;}
公共bool ResultSuccess
{
获取{return resultrrors.Messages.Count==0;}
}
}
因此,虽然需要为AutoMapper添加一个私有setter,但这是一个很小的代价,不需要使用复杂的映射来处理这个问题。对于当前的继承结构,AutoMapper将无法完成您希望它做的事情。由于目标结构与源结构具有相同的属性,因此这些属性也是只读的。AutoMapper不会映射到未声明setter的只读属性 您有几个选择:
- 使属性设置器显式私有。答案表明,更高版本的AutoMapper支持此功能。在本例中,它适用于4.x
- 将属性设置器设置为内部,以便只有此程序集的成员才能设置它。由于AutoMapper的最新版本将映射到私有setter,因此它们也应该映射到内部setter
- 使属性可设置
- 向下投射对象而不是映射(您已经提到您不想这样做,因为您的对象结构最终会发散)
- 使用公共setter对目标对象上的属性进行阴影处理。丑陋而且是奇怪虫子的好来源
public class SimpleManualCruiseBookingOutput : OzCpSimpleManualCruiseBookingOutput { public new OzCpResultErrors ResultErrors { get; set; } }
- 创建通过反射映射只读属性的帮助器不要这样做强>