自动映射器:将元组映射到元组



我在 ASP.NET MVC4项目中使用AutoMapper。我在映射 2 类问题和问题视图模型时遇到问题。这是我的两个模型类:

   public class Question
    {
      public int Id { get; set; }
      public string Content { get; set; }
      public Tuple<int, int> GetVoteTuple()
       {
         "some code here"
       }
    }
   public class QuestionViewModel
    {
      public int Id { get; set; }
      public string Content { get; set; }
      public Tuple<int, int> VoteTuple { get; set; }
    }

这是我的控制器代码:

   public class QuestionController: Controller 
    {
       public ActionResult Index(int id)
         {
            Question question = Dal.getQuestion(id);
            Mapper.CreateMap<Question, QuestionViewModel>()
                .ForMember(p => p.VoteTuple,
                m => m.MapFrom(
                s => s.GetVoteTuple()
            ));
            QuestionViewModel questionViewModel =
                        Mapper.Map<Question, QuestionViewModel>(question);
            return View(questionViewModel);
          }
     }

当我运行此代码时,QuestionViewModel中的 VoteTuple 属性具有空值。如何将 2 个类与元组属性映射?

谢谢。

默认情况下,通过 Automapper 无法从元组映射到元组,因为元组没有 setter 属性(它们只能通过构造函数初始化)。

您有 2 个选项:

1) 为自动映射器创建自定义解析程序,然后使用 .解析映射配置中的使用方法:.ForMember(p => p.VoteTuple, m => m.ResolveUsing<CustomTupleResolver>())

2)映射到属性/类,如下所示:

public class QuestionViewModel
{
  public int Id { get; set; }
  public string Content { get; set; }
  public int VoteItem1 { get; set; }
  public int VoteItem2 { get; set; }
}

然后:

.ForMember(p => p.VoteItem1, m => m.MapFrom(g => g.Item1))
.ForMember(p => p.VoteItem2, m => m.MapFrom(g => g.Item2))

您实际上不需要在视图模型中使用元组,因此我推荐第二个选项。

编辑

我看到您已经更新了代码,以便 GetVoteTuple() 是一个函数,而不是一个属性。在这种情况下,您可以像这样轻松调整代码:

.ForMember(p => p.VoteItem1, m => m.MapFrom(g => g.GetVoteTuple().Item1))
.ForMember(p => p.VoteItem2, m => m.MapFrom(g => g.GetVoteTuple().Item2))

您的CreateMap调用不正确:

Mapper.CreateMap<Question, QuestionViewModel>()
    .ForMember(p => p.VoteTuple,
        m => m.MapFrom(
        s => s.GetVoteTuple()
//-----------^
     ));

尝试使用 ResolveUsing 而不是 MapFrom(并在 lambda 中使用通用 s 参数而不是局部变量引用:

        Mapper.CreateMap<Question, QuestionViewModel>()
            .ForMember(p => p.VoteTuple,
            m => m.ResolveUsing(
            s => s.GetVoteTuple()
        ));

MapFrom用于直接映射属性。 由于您希望从函数调用的结果中"映射",因此ResolveFrom更合适。

此外,您只应在应用程序中调用CreateMap一次,通常在Application_Start中以 global.asax

试试这个:

 Mapper.CreateMap<Question, QuestionViewModel>()
                .ForMember(p => p.VoteTuple,op=>op.MapFrom(v=>new Tuple<int,int>(v.GetVoteTuple.Item1,v.GetVoteTuple.Item2)));

最新更新