C# Automapper未传输我的收藏项目

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

我正在使用AutoMapper 4.x

我有以下几节课:

/// <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在OzCpSimpleManualCruiseBookingOutputSimpleManualCruiseBookingOutput之间进行转换时,我的问题是结果被清除

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; }
    }
    
  • 创建通过反射映射只读属性的帮助器不要这样做


请不要在此处复制和粘贴项目代码。读取如此大的类名和属性是很困难的。为什么不能用逻辑相同的简单类进行更新呢?@PrasadKanaparthi在SO上发帖太有趣了。。。。你最终得到了太多“不要像这样发帖”的噪音,以至于它超过了答案大约300:1我可以控制数据,但我不能控制愚蠢的开发人员;-)。你的私人二传手搞定了!我无法用3.3.1测试这个问题,因为我已经升级到4.x,希望它能解决最初的问题,但它没有。唯一一件小事(我可以接受)是IOzCpAppServiceOutputBase将属性声明为readonly,而基类ozcpapperserviceoutputbase实现私有setter纯粹是为了AutoMapper。“但那是一个次要的问题。”“我很高兴听到你这么做了:)我将把它作为公认的答案提出来,如果你能把它标为公认的,我将不胜感激。再次感谢你的帮助。