AutoMapper:将元组映射到元组

时间:2014-02-28 14:20:34

标签: c# asp.net asp.net-mvc-4 automapper

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

   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);

          }
     }

当我运行此代码时,VoteTuple中的QuestionViewModel属性具有空值。如何使用Tuple属性映射2类?

感谢。

4 个答案:

答案 0 :(得分:1)

您的CreateMap来电不正确:

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

答案 1 :(得分:1)

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

您有两个选择:

1)为Automapper创建自定义解析器,然后在映射配置中使用.ResolveUsing方法:.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))

你真的不需要在你的视图模型中使用Tuple,所以我推荐第二个选项。

修改

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

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

答案 2 :(得分:0)

尝试使用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

}

答案 3 :(得分:0)

试试这个:

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