Ajax 自动映射UseValue、ResolveUsing或MapFrom重用上一次调用的值。是缓存还是什么?

Ajax 自动映射UseValue、ResolveUsing或MapFrom重用上一次调用的值。是缓存还是什么?,ajax,dynamic,asp.net-mvc-4,automapper,generic-collections,Ajax,Dynamic,Asp.net Mvc 4,Automapper,Generic Collections,我遇到的情况是,从第二次调用和后续调用(ajaxget调用)开始,AutoMapper重复使用以前的值(来自第一次调用的值,该值来自于单击操作链接)。这就像一个“缓存”问题 public virtual ActionResult List(int assessmentId, int? chapterId, bool? isMenuClick) { Mapper.CreateMap<Element, AssessmentQuestionViewModel>(). Fo

我遇到的情况是,从第二次调用和后续调用(ajaxget调用)开始,
AutoMapper
重复使用以前的值(来自第一次调用的值,该值来自于单击操作链接)。这就像一个“缓存”问题

public virtual ActionResult List(int assessmentId, int? chapterId, bool? isMenuClick)
{

    Mapper.CreateMap<Element, AssessmentQuestionViewModel>().
    ForMember(dest => dest.AssessmentId, opt => opt.MapFrom(e => assessmentId));

    ...

}
第一次,
questions
正常,即所有
AssessmentQuestionViewModel
对象都按照定义的
CreateMap
正确设置了
AssessmentId
属性

从第二次调用开始,它将重用第一次调用中的
assessmentId
,这会打乱我的业务逻辑,因为我希望它将
assessmentId
映射到更新后的
assessmentId
,并将其作为参数传递给
列表
方法

只是为了确保:我在代码中设置了一个断点,我可以看到
assessmentId
参数的值是正确的。只是返回的映射对象
问题
AssessmentId
属性中的值错误-该值与当前的
AssessmentId
值不同。据我所知,这些值应该相等,因为我要求AutoMapper使用当前值进行映射

我有AutoMapper 2.2.1-ci9000(预发行版),但我用以前的版本测试了它,我看到了同样的行为。我更新了预发行版,认为这种“不当行为”会消失


我认为这是一个错误。如果我错了,或者我试图以不受支持的方式使用它,请纠正我。:)

我认为这里的问题是您试图创建同一类型的多个映射,而AutoMapper不支持这些映射。每次调用
列表
操作时,您都会创建一个新映射(它有一个不同的
ForMember(…)
子句)。AutoMapper不会抛出异常,它只是忽略了重复映射,因此您在这里看到的不是错误,而是预期的行为

ForMember
实际上是在每个映射上调用的,但是,由于变量硬编码到表达式中,因此这里存在范围问题。作为一项工作,你可以做如下事情:

public class MyController
{
    public MyController()
    {
        // define mapping once, but make assessment expression dynamic
        Mapper.CreateMap<Element, AssessmentQuestionViewModel>().
            ForMember(dest => dest.AssessmentId, opt => opt.MapFrom(e => GetCurrentAssessmentId()));
    }

    private int GetCurrentAssessmentId()
    {
        return (int)TempData["AssessmentId"];
    }

    public ActionResult List(int assessmentId, ...)
    {
        // store current assessment temporarily
        TempData.Add("AssessmentId", assessmentId);
        // execute mapping
        var questions = Mapper.Map<IEnumerable<Element>, IEnumerable<AssessmentQuestionViewModel>>
 (Database.Elements.Where(e => !elementIds.Contains(e.ElementId) &&
                          e.Standard.ChapterId == chapterId));
    }
}
公共类MyController
{
公共MyController()
{
//定义一次映射,但使评估表达式动态
Mapper.CreateMap()。
FormMember(dest=>dest.AssessmentId,opt=>opt.MapFrom(e=>GetCurrentAssessmentId());
}
private int GetCurrentAssessmentId()
{
返回(int)TempData[“AssessmentId”];
}
公共行动结果列表(int评估ID,…)
{
//暂时存储当前评估
TempData.Add(“AssessmentId”,AssessmentId);
//执行映射
var questions=Mapper.Map
(Database.Elements.Where(e=>!elementIds.Contains(e.ElementId)&&
e、 Standard.ChapterId==ChapterId));
}
}
但是我会说,为了让它工作,你需要跨越很多障碍,在没有AutoMapper帮助的情况下手动设置属性会简单得多

var questions = Mapper.Map<IEnumerable<Element>, IEnumerable<AssessmentQuestionViewModel>>(...);
foreach (var q in questions)
{
    q.AssessmentId = assessmentId;
}
var-questions=Mapper.Map(…);
foreach(问题中的var q)
{
q、 AssessmentId=AssessmentId;
}

我认为这里的问题在于您试图创建相同类型的多个映射,而AutoMapper不支持这种映射。每次调用
列表
操作时,您都会创建一个新映射(它有一个不同的
ForMember(…)
子句)。AutoMapper不会抛出异常,它只是忽略了重复映射,因此您在这里看到的不是错误,而是预期的行为

ForMember
实际上是在每个映射上调用的,但是,由于变量硬编码到表达式中,因此这里存在范围问题。作为一项工作,你可以做如下事情:

public class MyController
{
    public MyController()
    {
        // define mapping once, but make assessment expression dynamic
        Mapper.CreateMap<Element, AssessmentQuestionViewModel>().
            ForMember(dest => dest.AssessmentId, opt => opt.MapFrom(e => GetCurrentAssessmentId()));
    }

    private int GetCurrentAssessmentId()
    {
        return (int)TempData["AssessmentId"];
    }

    public ActionResult List(int assessmentId, ...)
    {
        // store current assessment temporarily
        TempData.Add("AssessmentId", assessmentId);
        // execute mapping
        var questions = Mapper.Map<IEnumerable<Element>, IEnumerable<AssessmentQuestionViewModel>>
 (Database.Elements.Where(e => !elementIds.Contains(e.ElementId) &&
                          e.Standard.ChapterId == chapterId));
    }
}
公共类MyController
{
公共MyController()
{
//定义一次映射,但使评估表达式动态
Mapper.CreateMap()。
FormMember(dest=>dest.AssessmentId,opt=>opt.MapFrom(e=>GetCurrentAssessmentId());
}
private int GetCurrentAssessmentId()
{
返回(int)TempData[“AssessmentId”];
}
公共行动结果列表(int评估ID,…)
{
//暂时存储当前评估
TempData.Add(“AssessmentId”,AssessmentId);
//执行映射
var questions=Mapper.Map
(Database.Elements.Where(e=>!elementIds.Contains(e.ElementId)&&
e、 Standard.ChapterId==ChapterId));
}
}
但是我会说,为了让它工作,你需要跨越很多障碍,在没有AutoMapper帮助的情况下手动设置属性会简单得多

var questions = Mapper.Map<IEnumerable<Element>, IEnumerable<AssessmentQuestionViewModel>>(...);
foreach (var q in questions)
{
    q.AssessmentId = assessmentId;
}
var-questions=Mapper.Map(…);
foreach(问题中的var q)
{
q、 AssessmentId=AssessmentId;
}

Uhmmm。。。我想我明白你的意思。那么,你知道我应该如何处理这个映射吗?我需要将动态值分配给
Mapper.CreateMap
。根据您的说法,我必须只定义一次
CreateMap
。也许我可以这样做:
如果(!isMenuClick.HasValue){//CreateMap,因为它是对action方法的第一次调用}
,那么对于后续调用(Ajax调用),我只需调用
Mapper.Map
@LenielMacaferi即可看到我的更新。这里的目标是使初始映射的评估Id是动态的(因此没有硬编码的表达式)。一个简单的方法是从函数中返回它,这就是我现在看到的。我只是使用
foreach
方法设置值。我发布这个问题只是想知道为什么第一种方法不起作用。你的回答说明了一些问题!谢谢我的朋友……:)@莱尼尔·马卡费里就像我已经说明的那样,这是可以做到的,问题是——这值得付出额外的努力吗?就个人而言,对于一个单一的财产,我会说不:)完全正确。我也认为这不值得努力。我们走的是捷径