【问题标题】:AutoMapper: Mapping Tuple to TupleAutoMapper:将元组映射到元组
【发布时间】:2014-02-28 14:20:33
【问题描述】:

我在我的 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);

          }
     }

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

谢谢。

【问题讨论】:

  • 你用的是什么版本?此外,MapFrom 部分不是必需的,AutoMapper 自动映射 GetFoo() -> Foo(称为 Get 到属性的方法,没有 Get)。

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


【解决方案1】:

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

你有两个选择:

1) 为 Automapper 创建一个自定义解析器,然后在映射配置中使用 .ResolveUsing 方法:.ForMember(p =&gt; p.VoteTuple, m =&gt; m.ResolveUsing&lt;CustomTupleResolver&gt;())

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】:

    您的CreateMap 呼叫不正确:

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

    【讨论】:

    • 谢谢 Andrew,我更改了 'question' -> 's' 但它仍然有 null 值。
    • @user3286476:你能展示一下GetVoteTuple()的实现吗?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      试试这个:

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

      【讨论】:

        猜你喜欢
        • 2016-02-10
        • 1970-01-01
        • 1970-01-01
        • 2015-07-14
        • 2016-07-31
        • 1970-01-01
        • 1970-01-01
        • 2015-04-30
        • 2020-12-24
        相关资源
        最近更新 更多